In this article, we will take a look at the basic use of thread pools. In this article, we will learn how to use thread pools instead of explicitly creating threads
Creation of a thread pool
Since you want to use thread pools, you need to create them first. Java provides the Following classes for thread pool closers: * Creates a thread pool by following the following steps: * Creates a thread pool by following the following steps: * Creates a thread pool by following the following steps: * Creates a thread pool by following the following steps:
/ / create a thread pool size for Integer. MAX_VALUE, so is the infinite ExecutorService pool = Executors. NewCachedThreadPool (); / / create a capacity of 1 thread pool, its execution is serial ExecutorService pool = Executors. NewSingleThreadExecutor (); / / create a fixed size of thread pool ExecutorService pool = Executors. NewFixedThreadPool (10); / / periodic task thread pool ScheduledExecutorService pool = Executors. NewScheduledThreadPool (10);Copy the code
-
Executors. NewCachedThreadPool (), capacity of infinite thread pool, it is suitable for the task is very much, high concurrency scenario. For example, EventBus, which executes the task of listening for Event callbacks an unknown number of times, can use the thread pool for that policy.
-
Executors. NewSingleThreadExecutor (), the capacity of 1 thread pool, it is serial mission, performed a task to execute the next. The thread pool of this strategy is typically used to process serial tasks.
-
Executors. NewFixedThreadPool (10), a fixed capacity of thread pool, if received task, thread pool capacity has reached the set size, will be blocked.
-
Executors. NewScheduledThreadPool (10), a periodic task thread pool, can delay executed or cycle, can be used as a timer.
Submit tasks to the thread pool
Execute (); submit(); submit();
-
Execute (Runnable Runnable), executes a Runnable task object, so its execution returns no value.
-
Submit (Runnable Runnable), also executes a Runnable task object, but returns a Future object. The Future object can be retrieved by the get() method, but the overloaded method passes null, so even if the get() method is called, The value is also null.
-
Submit (Runnable Runnable,T result) returns the same Future object as the second overloaded method.
-
Submit (Callable Callable), pass in a Callable object, we know that Callable object has a return value, and Runnable is not return value.
-
invokeAny(Collection<? Extends Callable> Tasks) executes a collection of Callable tasks, randomly executing one of them and returning the result of the task. If the task throws an exception, the other Callable tasks are canceled.
-
invokeAll(Collection<? Extends Callable> Tasks), which executes all of the tasks in a collection of Callable tasks and returns List<Future>.
The sample
- Execute () to execute a Runnable with no return value.
/** * Submit the Runnable task */ private static voidexecuteByRunnable() {
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println("I'm doing a task in execute()"); }}); } // Output I execute the task in execute()Copy the code
- Submit () executes a Callable with a return value.
/** * Submit the Callable task */ private static voidsubmitByCallable() {
try {
ExecutorService pool = Executors.newCachedThreadPool();
Future<String> future = pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "I am the result"; }}); String result = future.get(); System.out.println("result: "+ result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }} // output result: I am the resultCopy the code
- InvokeAny (), which executes any of the tasks in the set.
/** * Randomly execute any task in the task set */ private static voidrunRandomTask() {
try {
ExecutorService pool = Executors.newCachedThreadPool();
ArrayList<Callable<String>> taskList = new ArrayList<>();
taskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "I'm result one."; }}); taskList.add(new Callable<String>() { @Override public String call() throws Exception {return "I am result two."; }}); taskList.add(new Callable<String>() { @Override public String call() throws Exception {return "I am result three."; }}); String result = pool.invokeAny(taskList); System.out.println("Operating Results:"+ result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }} // Output the run result: I am result 1Copy the code
- InvokeAll (), which executes all tasks in the task set.
/** * Perform all tasks */ private static voidrunAllTask() {
try {
ExecutorService pool = Executors.newCachedThreadPool();
ArrayList<Callable<String>> taskList = new ArrayList<>();
taskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "I'm result one."; }}); taskList.add(new Callable<String>() { @Override public String call() throws Exception {return "I am result two."; }}); taskList.add(new Callable<String>() { @Override public String call() throws Exception {return "I am result three."; }}); List<Future<String>> futures = pool.invokeAll(taskList);for (Future<String> future : futures) {
String result = future.get();
System.out.println("Get results:"+ result); } } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }} // Output get result: I am result 1 get result: I am result 2 Get result: I am result 3Copy the code
-
Compared with ScheduledExecutorService, which can execute periodic tasks, there are two methods: schedule() and scheduleAtFixedRate().
- Schedule (), delay execution.
/** * Delay execution */ private static void runTaskWithDelay(Runnable Runnable) {ScheduledExecutorService pool = Executors.newScheduledThreadPool(10); pool.schedule(runnable, 3, TimeUnit.SECONDS); } // call runTaskWithDelay(new)Runnable() { @Override public void run() { System.out.println("I'm a task in a thread pool."); System.out.println("I delayed execution by 3 seconds..."); }}); // Output I am a task in the thread pool and I delayed execution by 3 seconds...Copy the code
- ScheduleAtFixedRate (), executed periodically.
/** * Periodic task execution */ private static void runTaskWithCycle(Runnable Runnable) {ScheduledExecutorService Pool = Executors.newScheduledThreadPool(10); Pool. scheduleAtFixedRate(runnable, 0, 1, timeunit.seconds); } // call runTaskWithCycle(new)Runnable() { @Override public void run() { System.out.println("I'm a cyclical assignment."); }}); // Output I'm a periodic task I'm a periodic task I'm a periodic task I'm a periodic taskCopy the code
Closing the thread pool
If we need to shutdown the thread pool, there are two methods, shutdown() and shutdownNow().
- Shutdown () does not close the thread pool immediately, but waits for all tasks to complete
/** * Closes the thread pool, waiting for the task to complete */ private static voidshutdownThreadPool() {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);
pool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("I'm the result of the execution..."); } }, 1, TimeUnit.SECONDS); pool.shutdown(); } // Output is the result of execution...Copy the code
- ShutdownNow () forces the thread pool to be closed without waiting for the task to complete.
/** * close the thread pool immediately */ private static voidshutdownNowThreadPool() {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);
pool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("I'm the result of the execution..."); } }, 1, TimeUnit.SECONDS); pool.shutdownNow(); } // There is no output because the task was canceledCopy the code
conclusion
Frequent use of threads You must use thread pools to avoid resource consumption caused by frequent creation and destruction of threads. In this article, we explained the Api for creating thread pools quickly. In the next article, we’ll look at customizing thread pool parameters.