The java.util.concurrent package provides classes about multi-threaded operations. The commonly used ones are ExecutorService and its implementation classes (such as ThreadPoolExecutor, etc.), Executor, Executors, Future, Callable, etc.
1. ExecutorService (inherited from Executor) interface: provides some asynchronous multi-threaded operation methods, such as execute(), submit(), shutdown(), shutdownNow(), etc.
2. Executor interface: execute the submitted task (thread), with only one method executed(Runnable a)
2. Executors class: Provides some factory methods and some public methods to operate Executor subclasses and ThreadFactory, etc., such as newXXX(), xxxThreadFactory(), etc.
3. Futrue interface: represents the thread execution result, provides methods to obtain thread execution result and cancel threads, such as get(), cancle(), etc.
4. Callable interface: The thread with return value is provided by JDK1.5 to execute a new interface
Make simple records of the understanding of ExecutorService and Future
Code:
public class Main { private static int count = 0; public static void main(String[] args){ List<Future> resultList = new LinkedList<>(); /** * Executors.newCachedThreadPool() Create a thread cache pool. If the thread is not used in 60s, the thread will be stopped and removed from the cache pool* Executors.newScheduledThreadPool() Create a thread pool with fixed capacity, and the threads inside execute according to the set scheduling time* Executors.newFixedThreadPool() Have a thread cache pool with fixed capacity* Executors.newSingleThreadExecutor() A thread cache pool with one capacity has only one thread*/ ExecutorService executorService = Executors.newCachedThreadPool(); for(int i=0; i<10; i++){ Future future = executorService.submit(new Callable<String>() { @Override public String call() { try { System.out.println(Thread.currentThread().getName()); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } int count = Main.count; System.out.println(Thread.currentThread().getName() + "..start Main count:..." + count); Main.count = ++count; System.out.println(Thread.currentThread().getName() + "..end Main count:..." + Main.count); return Thread.currentThread().getName(); } }); resultList.add(future); } executorService.shutdown(); for(Future future: resultList){ try { System.out.println(future.get() + "..is over..."); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } System.out.println("main thread end..."); }}Output:
pool-1-thread-1pool-1-thread-2pool-1-thread-3pool-1-thread-4pool-1-thread-5pool-1-thread-6pool-1-thread-7pool-1-thread-8pool-1-thread-9pool-1-thread-10pool-1-thread-1..start Main count:...0pool-1-thread-2..start Main count:...0pool-1-thread-3..start Main count:...1pool-1-thread-2..end Main count:...1pool-1-thread-1..end Main count:...1pool-1-thread-3..end Main count:...1pool-1-thread-2..end Main count:...1pool-1-thread-1..end Main count:...1pool-1-thread-3..end Main count:...2pool-1-thread-1..is over...pool-1-thread-2..is over...pool-1-thread-4..start Main count:...2pool-1-thread-3..is over...pool-1-thread-4..end Main count:...3pool-1-thread-4..is over...pool-1-thread-5..start Main count:...3pool-1-thread-5..end Main count:...4pool-1-thread-5..is over...pool-1-thread-6..start Main count:...4pool-1-thread-6..end Main count:...4pool-1-thread-6..end Main count:...4pool-1-thread-6..end Main count:...4pool-1-thread-6..end Main count:...4pool-1-thread-6..end Main count:...5pool-1-thread-6..is over...pool-1-thread-7..start Main count:...5pool-1-thread-7..end Main count:...6pool-1-thread-7..is over...pool-1-thread-8..start Main count:...6pool-1-thread-8..end Main count:...7pool-1-thread-8..is over...pool-1-thread-9..start Main count:...7pool-1-thread-9..end Main count:...8pool-1-thread-9..is over...pool-1-thread-10..start Main count:...7pool-1-thread-9..end Main count:...8pool-1-thread-9..is over...pool-1-thread-10..start Main count:...8pool-1-thread-9..is over...pool-1-thread-10..start Main count:...8pool-1-thread-10..end Main count:...9pool-1-thread-10..is over...main thread end... //The main thread ends after all threads have completed execution
The console prints the output result above after waiting for 5 seconds. The reason is that when all threads start, it is a concurrent operation and will wait for 5 seconds. So overall, it seems that it only waited for 5 seconds. This is a concurrent operation.
Summarize:
1. The difference between the execute() method and the submit() method provided by ExecutorService:
a. The execute() method only accepts instances of Runnable type, so it cannot get the return value, nor can it dynamically obtain the thread execution situation.
b. The submit() method accepts Runnable and Callable instances and will return the Future instance. The get() method of the Future instance can obtain the thread execution return value and throw thread execution exceptions. So if you want to get the result returned by thread execution and be able to handle possible exceptions during thread execution, or if you want to cancel thread execution in the middle, you can use the submit() method
2. Through the output, you can see that the main method (main thread) ends after all threads have completed execution. The reason:
a. Get the Future instance through the submit() method, and get the thread return result through the get() method of the Future instance. The get() method of the Future instance will wait for the thread to execute before returning, so the main method will wait for all child threads to end before ending
b. If the for loop marked with red above is removed, the main method (main thread) will end early without waiting for all child threads to end
Replenish:
1. When multiple threads execute concurrently, if an exception occurs in one of the threads and is not processed, the thread will automatically stop execution, but the other threads will still execute normally. This is why tomcat can continue to provide services when an exception occurs in tomcat request.
2. tomcat provides a thread pool and a waiting pool. Each request will restart a new thread to process the request. If the threads in the thread pool are used up, it will be put into the waiting pool and wait. When a thread is released back into the thread pool, a thread will be assigned to process the requests in the waiting pool.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.