java开源长了, 代码久了,网上对于线程那是众说纷纭,一直萦绕我心头的,jdk线程池好仍是spring线程池好?html
结果发现,spring生命周期管理的线程池,其底层就是私有ThreadPoolExecutor类,spring(具体管理ThreadPoolTaskExecutor类)只是对其一种封装调用而已;java
而咱们平常使用jdk线程池 - Executor框架, ThreadPoolExecutor是Executor框架的核心实现类;spring
说到底,jdk线程池与spring线程池都是在使用ThreadPollExecutor基础上开发;json
古老的extend,implment Runnable的实现线程的方式就不说了,也就是测试类写写缓存
科普下, jdk8 lambda格式方便快捷的使用多线程
new Thread(() -> System.out.println("线程打印...")).start();
炒的火热jdk线程池的的核心实现类。app
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
经过idea源码方法看到, Executors类下, 有很多快捷建立线程池方法 (idea查看类方法alt+7), 下面介绍经常使用的5种建立方法;框架
FixedThreadPool是可重的固定线程数的线程池。异步
//建立FixedThreadPool Executors.newFixedThreadPool(5); //建立所须要的参数 public static ExecutorService newFixedThreadPool(int nThreads) { //最后调用的都是ThreadPoolExecutor return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
咱们只须要传如须要建立的线程的数量,也就是线程池的大小。咱们能够看到构造方法,传入的线程的数量就是核心线程的数量。也就是FixedThreadPool会建立固定数量核心线程的线程池,而且这些核心线程不会被回收,任务超过线程的数量将存入队列中。async
该线程池是根据须要去建立线程的。
//建立缓存线程池 Executors.newCachedThreadPool(); //构造方法 public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
咱们能够看出,这里面的核心线程数是0,而线程的最大值是Integer.Max_VALUE。闲置超时间是一分钟。默认队列能够保证任务顺序的执行。CacheThreadPool适合大量的须要当即处理而且耗时较少的任务。
该类是使用单个线程的线程池。
//建立方法 Executors.newSingleThreadExecutor(); //构造方法 public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
corePoolSize和maximumPoolSize都是1,意味着SingleThreadExecutor只有一个核心线程。其余的参数和FixedThreadPool同样。若是已经建立了一个线程再来一个任务的时候会将该任务加入到任务队列里面,确保了全部任务的执行顺序。
ScheduledThreadPool是一个能实现定是和周期性任务的线程池。
//建立 Executors.newScheduledThreadPool(5); //构造方法 public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); } //最后仍是调用的 ThreadPoolExecutor的构造方法。
当执行任务的时候,会先将任务包装成ScheduledFutrueTask并添加到DelayedWorkQueue里面,当没超过corePoolSize的时候,会建立线程,人后去DelayedWorkQueue队列里面去拿任务,并非当即的执行。当执行完任务的时候会将ScheduledFutrueTask中的time变量改成下次要执行的时间并放回DelayedWorkQueue中。
springContext.xml配置管理, 其线程池生命周期由spring来管理
<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数,默认为1 --> <property name="corePoolSize" value="10" /> <!-- 最大线程数,默认为Integer.MAX_VALUE --> <property name="maxPoolSize" value="50" /> <!-- 队列最大长度,通常须要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE <property name="queueCapacity" value="1000" /> --> <!-- 线程池维护线程所容许的空闲时间,默认为60s --> <property name="keepAliveSeconds" value="300" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 --> <property name="rejectedExecutionHandler"> <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 --> <!-- CallerRunsPolicy:主线程直接执行该任务,执行完以后尝试添加下一个任务到线程池中,能够有效下降向线程池内添加任务的速度 --> <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会致使被丢弃的任务没法再次被执行 --> <!-- DiscardPolicy:抛弃当前任务、暂不支持;会致使被丢弃的任务没法再次被执行 --> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean>
注解又分为 默认非线程池方式,线程池方式,这里已线程池方式为例子
<?xml version="1.0" encoding="UTF-8"?> <!--Spring框架的xml标签订义文档, 可访问http://www.springframework.org/schema/task/查看最新task组件的xml标签文档--> <beans xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <!--扫描项目实例化@Component,@Service,@Controller修饰的类--> <context:component-scan base-package="com.your_app" /> <!-- 在代码中@Async不加参数就会使用task:annotation-driven标签订义的executor--> <task:annotation-driven executor="myExecutor"/> <!-- 在代码中@Async("myExecutor")能够显式指定executor为"myExecutor"--> <task:executor id="myExecutor" pool-size="5-25" queue-capacity="100" rejection-policy="CALLER_RUNS"/> </beans>
@Async void doSomething(String s) { //能够带参数! // this will be executed asynchronously }
具体配置欢迎观看
https://blog.csdn.net/caib1109/article/details/51623089
调用发现,其org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor 类, 源码查看,
初始化,也是使用ThreadPoolExecutor实现操做,具体指示设置对应的参数值而已;
好了 查看到此结束
文章涉及来源:
SpringMVC异步处理之@Async(附源代码 - 单元测试经过)
https://blog.csdn.net/caib1109/article/details/51623089
http://www.javashuo.com/article/p-thfurkjh-gd.html
Java多线程-五中线程池分析以及AnsyncTask源码分析