Implementation of multithreading

Posted by lukegw on Sat, 09 Oct 2021 11:05:44 +0200

Implementation of multithreading

1. Inherit Thread class

    (1) define a class to inherit Thread and override the run() method;
    (2) create subclass objects of Thread class;
    (3) call start() to start a new thread.

//The main thread and the custom thread execute concurrently
public class thread {
    public static void main(String[] args) {
    	//2. Create a subclass object of the Thread class
        MyThread myThread = new MyThread();     
        //3. Call start() to start a new thread
        myThread.start();                       

        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1. Define a class that inherits Thread and overrides the run() method
class MyThread extends Thread{              
    public void run(){                      
        for (int i = 0; i < 3000; i++) {    
            System.out.println("aaaaa");
        }
    }
}

2. Implement Runnable interface

    (1) define a class to implement the Runnable interface and rewrite the run() method;
    (2) create a subclass object of user-defined Runnable;
    (3) create a Thread object and pass Runnable as a parameter to the Thread constructor;
    (4) call start() to start a new thread.

//The main thread and the custom thread execute concurrently
public class thread {
    public static void main(String[] args) {
    	//2. Create a subclass object of a custom Runnable
        MyRunnable myRunnable = new MyRunnable();   
		//3. Create a Thread object and pass Runnable as a parameter to the Thread constructor
        Thread thread = new Thread(myRunnable);     
        //4. Call start() to start a new thread
        thread.start();                             

        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1. Define a class to implement the Runnable interface and override the run() method
class MyRunnable implements Runnable {      
    @Override                               
    public void run() {
        for (int i = 0; i < 3000; i++) {   
            System.out.println("aaaaa");
        }
    }
}

3. Implement Callable interface

    (1) define a class to implement the Callable interface and override the call() method;
    (2) create the instantiation object of the Callable subclass;
    (3) create FutureTask object and transfer Callable object into FutureTask construction method;
    (4) instantiate the Thread object and pass in the FutureTask object in the construction method;
    (5) call start() to start a new thread.

//The main thread and the custom thread execute concurrently
public class thread {
    public static void main(String[] args) {
        //2. Create an instantiated object of a subclass of Callable
        MyCallable myCallable = new MyCallable();
        //3. Create FutureTask object and pass Callable object into FutureTask constructor
        FutureTask futureTask = new FutureTask<String>(myCallable);
        //4. Instantiate the Thread object and pass in the FutureTask object in the constructor
        Thread thread = new Thread(futureTask);
        //5. Call start() to start a new thread
        thread.start();
        
        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1. Define a class to implement the Callable interface and override the call() method
class MyCallable implements Callable{
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 3000; i++) {
            System.out.println("aaaaaaaa");
        }
        return "0";
    }
}

4. Anonymous inner classes of types 1, 2 and 3

5. Thread pool based approach

  we know that threads and database connections are very valuable resources. It is a waste of resources to create when needed and destroy when not needed. Then we can use the cache strategy, that is, using thread pool. Of course, we don't need to implement thread pool, and the official jdk also provides us with API.

public class CreateThreadDemo12_ThreadPool {
    public static void main(String[] args) throws Exception {
        // Create a fixed size thread pool
        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        while (true) {
            // Submit multiple threaded tasks and execute them
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    printThreadInfo();
                }
            });
        }
    }

    /**
     * Outputs information about the current thread
     */
    private static void printThreadInfo() {
        System.out.println("The currently running thread name is: " + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

  the output result is:

The currently running thread name is pool-1-thread-1
The currently running thread name is pool-1-thread-2
The currently running thread name is pool-1-thread-4
The currently running thread name is pool-1-thread-3
The currently running thread name is pool-1-thread-7
The currently running thread name is pool-1-thread-8
The currently running thread name is pool-1-thread-9
The currently running thread name is pool-1-thread-6
The currently running thread name is pool-1-thread-5
The currently running thread name is pool-1-thread-10

The difference between inheriting Thread class and implementing Runnable interface:

   1. The implementation of Runnable interface can avoid the limitation of single inheritance and has strong robustness.
   2. Runnable can share resources, and multiple threads can process the same resource at the same time.
   3. Threads of Thread class run independently, and resources are not shared.
  4. The inherited Thread class is no longer inherited by other classes.

Differences between implementing Runnable interface and Callable interface:

   1. The core of Callable is the call() method, which allows return values; The core of Runnable is the run() method, which has no return value.
  2. The call() method can throw exceptions, but the run() method cannot.
  3, Callable and Runnable can be applied to executor yes, while Thread class only supports Runnable.

Topics: Java Eclipse Hibernate JavaSE