spring Learning (twenty-eight) - @ Async thread pool

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.

 

 

 

Guess you like

Origin www.cnblogs.com/gllegolas/p/11817234.html