Before using java thread pool, we are the first to realize themselves through writing ThreadPoolExecutor thread pool class, and then write multithreaded class, execute a method using a thread pool to execute multiple threads Classes.
In the spring, you can by @Async (value = "beanId") annotation to use thread pool multithreaded programming.
Create a thread pool, there are two ways, one is the configuration file, is through java programming.
1, created by the thread pool configuration file, add the following configuration in the spring configuration file, the configuration file you want to scan multiple open comment thread class where the package:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"
default-autowire="byName">
<Description> My spring thread pool configuration </ description>
<! - default configuration parameters when @Async Notes default asynchronous task thread pool myExecutor -> <Task: Annotation-Driven Executor = "myExecutor" />
<- the first thread pool -!>
<task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10"/>
<! - The second thread pool ->
<task:executor id="myExecutor" pool-size="15-50" queue-capacity="100" keep-alive="60" rejection-policy="CALLER_RUNS"/> </beans>
<Task: executor /> configuration parameters:
id: When multiple executor, are @Async ( "id") specify; also known as a prefix thread name.
pool-size:格式"core size-max size"
core size: minimum number of threads, the default: 1
max size: maximum number of threads, the default: Integer.MAX_VALUE
queue-capacity: When the minimum number of threads that have been occupied by full, new tasks can be put inside the queue, the queue when the capacity is also filled, pool which will create a new thread to deal with this task until the total number of threads reached max size, then the system will reject the task and throw TaskRejectedException an exception (in the case of default configuration, you can decide how to handle this situation by rejection-policy). The default value is: Integer.MAX_VALUE
keep-alive: those threads exceed the core size of the task is completed, and then after this length of time (in seconds) is to be finalized
rejection-policy: When the pool has reached max size, how to deal with new tasks
ABORT (default): TaskRejectedException throws an exception, then do not execute DISCARD: not performed, no exception is thrown
DISCARD_OLDEST: discard the oldest queue that task
CALLER_RUNS: not in the new thread to perform the task, but there is a thread where the caller to perform
Plus @Async annotation methods
package cn.leadeon.message.test; import org.springframework.context.annotation.ImportResource; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component @ImportResource ( " the CLASSPATH: /config/spring-threadpool.xml " ) public class AsyncTest {
// This method is the default annotation value parameter, using the default thread pool as myExecutor @Async public void test1() { . System OUT .println ( " asynchronous execution !!! test1 " ); System.out.println("线程id:" + Thread.currentThread().getId()); . System OUT .println ( " Thread Name: " + . Thread.currentThread () getName ()); }
// This method has a parameter (value = "asyncExecutor"), using a thread pool asyncExecutor
@Async(value="asyncExecutor") public void test2() { System.out.println ( "asynchronous execution test2 !!!"); System.out.println("线程id:" + Thread.currentThread().getId()); System.out.println ( "Thread name:". + Thread.currentThread () getName ()); }
}
That is executed in the new thread when calling outside testAsync method, the above <task: annotation-driven /> actuator to maintain the thread.
Summary: first with the context: component-scan to scan the notes, so that spring can recognize @Async comment, then task: annotation-driven to drive @Async notes, and you can specify the default thread executor executor. So when a @Async annotated method or class invoked, a thread of execution will create a new thread to execute.
2, pay attention to the point: @EnableAsync notes and <task: annotation-driven executor = "messageExecutor" /> equivalent, both only use one, or start being given
Executor create a new configuration class, the way to @EnableAsync notes moved here:
@Configuration @EnableAsync public class ExecutorConfig { /** Set the ThreadPoolExecutor's core pool size. */ private int corePoolSize = 10; /** Set the ThreadPoolExecutor's maximum pool size. */ private int maxPoolSize = 200; /** Set the capacity for the ThreadPoolExecutor's BlockingQueue. */ private int queueCapacity = 10; @Bean public Executor mySimpleAsync() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setThreadNamePrefix("MySimpleExecutor-"); executor.initialize(); return executor; } @Bean public Executor myAsync() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setThreadNamePrefix("MyExecutor-"); // rejection-Policy: When the pool has reached max size, how to handle the new tasks // CALLER_RUNS: perform tasks not in the new thread, but there is a thread where the caller to perform executor.setRejectedExecutionHandler ( new new ThreadPoolExecutor.CallerRunsPolicy () ); executor.initialize(); return executor; } }
This defines two different Executor, resets the second pool has been reached when the processing method max size; prefix specifying the thread name.
Writing multithreaded class uses the thread pool:
@Component public class AsyncTaskDemo4 { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async("mySimpleAsync") public Future<String> doTask1() throws InterruptedException{ logger.info("Task1 started."); long start = System.currentTimeMillis(); Thread.sleep(5000); long end = System.currentTimeMillis(); logger.info("Task1 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task1 accomplished!"); } @Async("myAsync") public Future<String> doTask2() throws InterruptedException{ logger.info("Task2 started."); long start = System.currentTimeMillis(); Thread.sleep(3000); long end = System.currentTimeMillis(); logger.info("Task2 finished, time elapsed: {} ms.", end-start); return new AsyncResult<>("Task2 accomplished!"); } }
Test Results:
2018-09-07 22:41:44.429 INFO 13640 --- [ main] com.work.spring.thread.TaskTests2 : Started TaskTests2 in 4.179 seconds (JVM running for 5.853) 2018-09-07 22:41:44.525 INFO 13640 --- [ MyExecutor-1] c.w.spring.thread.demo4.AsyncTaskDemo4 : Task2 started. 2018-09-07 22:41:44.525 INFO 13640 --- [impleExecutor-1] c.w.spring.thread.demo4.AsyncTaskDemo4 : Task1 started. 2018-09-07 22:41:47.526 INFO 13640 --- [ MyExecutor-1] c.w.spring.thread.demo4.AsyncTaskDemo4 : Task2 finished, time elapsed: 3001 ms. 2018-09-07 22:41:49.526 INFO 13640 --- [impleExecutor-1] c.w.spring.thread.demo4.AsyncTaskDemo4 : Task1 finished, time elapsed: 5001 ms. 2018-09-07 22:41:50.524 INFO 13640 --- [ main] com.work.spring.thread.TaskTests2 : Task1 result: Task1 accomplished! 2018-09-07 22:41:50.524 INFO 13640 --- [ main] com.work.spring.thread.TaskTests2 : Task2 result: Task2 accomplished! 2018-09-07 22:41:50.524 INFO 13640 --- [ main] com.work.spring.thread.TaskTests2 : All tasks finished. 2018-09-07 22:41:50.528 INFO 13640 --- [ Thread-3] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@747f281: startup date [Fri Sep 07 22:41:40 CST 2018]; root of context hierarchy 2018-09-07 22:41:50.532 INFO 13640 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'myAsync'
Prefix thread name has changed, we can see two different task using a thread pool.