Implementation of java multithreading and thread pool
Java implements multithreading in three ways: Inheriting the Thread class, implementing the runnable interface, and using ExecutorService, Callable, and Future to implement multithreading with returned values. The implementation methods of the first two threads do not return values. The third implementation method can obtain the return values of the thread execution.
I. inherit from java. lang. Thread class
Public class MyThread extends Thread {@ Overridepublic void run () {System. out. println ("my thread begin. "); try {// sleep 1000 ms Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println ("my thread over. ");} public static void main (String [] args) {MyThread thread = new MyThread (); thread. start ();}}
2. Implement the java. lang. Runnable interface
Public class MyThread implements Runnable {@ Overridepublic void run () {System. out. println ("my thread begin. "); try {// sleep 1000 ms Thread. sleep (1000); // do something ...} catch (InterruptedException e) {e. printStackTrace ();} System. out. println ("my thread over. ");} public static void main (String [] args) {Thread thread = new Thread (new MyThread (); thread. start ();}}
The implementation of the Runnable interface is more flexible than the inheritance of the Thread class, because Java is a single inheritance, and the inheritance of a class can no longer inherit another class, and the interface can implement multiple. However, no matter whether the Thread class is inherited or the Runnable interface is implemented, the return value of multithreading cannot be obtained. Unless an additional variable is used, a variable is modified in the run method and used elsewhere, this implementation method is more "chicken ribs ".
3. Implement the java. util. concurrent. Callable Interface
Public class MyThread implements Callable{@ Overridepublic Object call () throws Exception {System. out. println ("my thread begin. "); try {// sleep 1000 ms Thread. sleep (1000);} catch (InterruptedException e) {e. printStackTrace ();} System. out. println ("my thread over. "); return" OK ";} public static void main (String [] args) {// create a thread pool ExecutorService pool = Executors. newFixedThreadPool (2); FutureF = pool. submit (new MyThread (); // close the thread pool. shutdown (); try {System. out. println (f. get ();} catch (InterruptedException e) {e. printStackTrace ();} catch (ExecutionException e) {e. printStackTrace ();};}}
By creating a thread pool and submitting a Callable task, you can use the Future class to obtain the return value of the thread. When you call the get () method of Future, if the task is not completed, it is blocked until the task is completed. As noted in get (): Waits if necessary for the computation to complete, and then retrieves its result.
The ExecutorService interface in the code above inherits from the Executor interface. The implementation of Executor is based on the producer-consumer mode. The executor of the submitted task is the producer (which generates the work units to be completed), and the thread that executes the task is the consumer (consuming these work units ). To implement a producer-consumer design, using Executor is usually the easiest way.
The Executors class provides several methods to create a thread pool. The ExecutorService interface is also implemented through the thread pool created by Exectors. The method is as follows:
1. fixed-size thread pool: newFixedThreadPool (int nThreads)
Create a fixed thread pool. Each time a task is submitted, a thread is created until the thread reaches the maximum size of the thread pool. The size of the thread pool remains unchanged once it reaches the maximum value. If a thread ends due to an execution exception, the thread pool will add a new thread.
2. single-task thread pool: Executors. newSingleThreadExecutor ()
Creates a single-threaded thread pool. This thread pool only has one thread working, which is equivalent to a single thread serial execution of all tasks. If this unique thread ends due to an exception, a new thread will replace it. This thread pool ensures that all tasks are executed in the order they are submitted.
3. Variable-size thread pool: Executors. newCachedThreadPool ()
Create a cacheable thread pool. If the thread pool size exceeds the thread required to process the task, some Idle threads (not executed in 60 seconds) will be reclaimed. When the number of tasks increases, this thread pool can intelligently add new threads to process tasks. This thread pool does not limit the thread pool size. The thread pool size depends entirely on the maximum thread size that can be created by the operating system (or JVM.
4. Delayed thread pool: Executors. newScheduledThreadPool (int corePoolSize)
Creates an infinite thread pool. This thread pool supports regular and periodic task execution requirements.
Note: The shutdown () method does not terminate the execution of the thread, but prohibits the addition of new tasks in the Executor.