Introduce the ExecutorService

ExecutorService is an interface defined by the Java thread pool, in the java.util.Concurrent package, in which methods related to background task execution are defined.

The Java API has two implementations of the ExecutorService interface, so these are concrete implementations of thread pools.

1. ThreadPoolExecutor
2. ScheduledThreadPoolExecutor
Copy the code

The ExecutorService also inherits the Executor interface.

Solid lines represent inheritance and need to represent implementation

ExecutorServiceThe creation of

Java provides a factory class Executors to create various thread pools.

  • NewCachedThreadPool Creates a cacheable thread pool, with the flexibility to recycle idle threads if the pool length exceeds processing requirements, or create new threads if there are none to recycle.
  • NewFixedThreadPool Creates a thread pool of fixed length that controls the maximum number of concurrent threads, and the excess threads wait in the queue.
  • NewScheduledThreadPool Creates a thread pool of fixed length that can execute tasks periodically.
  • NewSingleThreadPool creates a single-threaded thread pool that uses only one thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO,LIFO).

Executors is a factory class, it is all the method returns the ThreadPoolExecutor and ScheduledThreadPoolExecutor the two instances of the class.

ExecutorServiceThe use of

ExecutorService executorService = Executors.newFixedThreadPool(10); Executorservice.execute (new Runnable() {public void run() {system.out.println (" executorService.execute "); }}); executorService.shutdown();Copy the code

ExecutorServiceThe execution method of

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(…)
  • invokeAll(…)

execute(Runnable)The execution result cannot be obtained

A Runnable instance is received and executed asynchronously

ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); }}); executorService.shutdown();Copy the code

There is no way to obtain execution results.

submit(Runnable)You can determine if the task is complete

Submit (Runnable) returns one more Future than execute(Runnable), which can be used to determine whether the submitted task has been completed.

Future future = executorService.submit(new Runnable() { public void run() { System.out.println("Asynchronous task"); }}); future.get(); //returns null if the task has finished correctly.Copy the code

If the task completes,future.get() returns null and future.get blocks.

submit(Callable)Returns can be obtained

Submit (Callable) is similar to submit(Runnable) in that it returns a Future object, but otherwise receives an implementation of a Callable. The Call () method in the Callable interface returns a value, The run() method in the Runnable interface is void and has no return value

Future future = executorService.submit(new Callable(){ public Object call() throws Exception { System.out.println("Asynchronous Callable"); return "Callable Result"; }}); System.out.println("future.get() = " + future.get());Copy the code

If the task completes,future.get will return the result returned by the Callable execution, and future.get() will block.

invokeAny(…)

invokeAny(…) Method receives a collection of Callable tasks, and executing this method does not return a Future, but the result of one of the Callable tasks. This method also does not guarantee which task will be returned, but one or the other

ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 1"; }}); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 2"; }}); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 3"; }}); String result = executorService.invokeAny(callables); System.out.println("result = " + result); executorService.shutdown();Copy the code

Each execution returns a result, and the result is variable, either “Task2” or “Task1” or something else.

invokeAll(...)

invokeAll(…) With invokeAny (…). Similarly, it receives a collection of Callable tasks, but returns a List of Future objects for each Callable task.

ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 1"; }}); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 2"; }}); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 3"; }}); List<Future<String>> futures = executorService.invokeAll(callables); for(Future<String> future : futures){ System.out.println("future.get = " + future.get()); } executorService.shutdown();Copy the code

The thread poolExecutorServiceThe closing of the

To shutdown the threads executing within the ExecutorService, you can call the executorservice.shutdown () method. ExecutorService does not shutdown immediately after the shutdown() method is called, but it does not accept new tasks until all current threads have completed execution, and all tasks submitted before shutdown() are executed.

If we want to close the ExecutorService immediately, we can call the ExecutorService. ShutdownNow () method. This action skips all tasks in progress and submitted tasks that have not yet been executed. However, it does not guarantee that the tasks being performed will either stop or finish.

Follow wechat official number: [entry] to unlock more knowledge points