Java四种线程池
来源:互联网 发布:不错吧源码 编辑:程序博客网 时间:2024/06/07 01:40
遇到了上传图片的功能,之前由于上传图片数量少,没有使用线程池,现在要最多支持30张图片上传,再像之前上传多少张图片,就开启多少个线程就有点行不通了,所以使用了线程池。
一、线程池 ExecutorService的基本使用
- 创建线程池对象
//使用定长类线程池newFixedThreadPool的方式演示 ExecutorService fixedThreadPool= Executors.newFixedThreadPool(3);
- 执行
MyThread为要执行的任务对象
for (int i = 0; i < 10; i++) { fixedThreadPool.execute(new MyThread(i+""));}
3.关闭线程池
fixedThreadPool.shutdown();//所有任务执行完毕之后,线程池关闭
二、Java四种线程池
1. newFixedThreadPool 线程池
创建一个固定长度的线程池,比如长度为N,最多同时有N个线程在并发执行,其余的线程在排队等待
//n 为线程池长度,自己觉得是多少ExecutorService fixedThreadPool =Executors.newFixedThreadPool(n);
newFixedThreadPool 就好比去银行办理业务(每个人都是一个要执行的线程任务),银行开了三个办公窗口(线程池长度为3),最多同时有3个人在办理业务(3个线程并发执行任务),其余的人在排队(未执行的线程任务在排队),顾客办理完业务走人(单个线程任务执行完结束),窗口为下一个轮到的人办理业务,而不是关闭当前窗口,又开一个新窗口办理业务(排队的线程任务,使用之前的线程执行,而不是新建线程)。
但是,注意一点,执行是没有一定顺序的,并没有先来先执行,下一个轮到谁,只能看cpu心情。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { fixedThreadPool.execute(new MyThread(i+"")); }
执行以上代码,结果如下:
可以看到,只有某一任务执行完毕,才有下一个任务的开始,保持同时有三个线程在执行任务。
2. newSingleThreadExecutor
从名字可知,单线程池,只创建了一个线程。但是可以保证执行顺序。
类似银行只开了一个窗口,按进门拿的号顺序执行。
ExecutorService newSingleThreadPool = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { newSingleThreadPool.execute(new MyThread(i+"")); }
执行以上代码,结果如下:
可以看出,同时只有一个线程在执行,但是可以保证线程任务的执行顺序是按execute方法执行顺序来执行的。
试了一下,和newFixedThreadPool的长度为一,执行结果一样。 即Executors.newFixedThreadPool(1)的效果一样。
3.newCachedThreadPool
缓存型的线程池,可以这样理解:银行有足够的窗口为顾客提供服务,前n个顾客依次进门的时候,为每个顾客都新开一个窗口服务。当第N+1个顾客进门前,之前进门的某个或者某些个顾客办完业务走人了,这样就有一些个窗口空闲下来了,此时,就使用闲置下来的窗口为新来的客户服务,不再新开窗口了。所以:
1。如果没有空闲线程,新开线程执行任务
2。如果有已经执行完任务的线程空闲,使用闲置的线程执行任务
3。如果线程空闲一定时间(默认60s),没有任务要执行,就关闭了
比较适合执行任务时间短的任务
ExecutorService executorService=Executors.newCachedThreadPool(); for(int i=0;i<1000;i++) { executorService.execute(new MyThread(i+"")); }
4 newScheduledThreadPool
线程池对象是ScheduledThreadPoolExecutor ,执行用schedule执行,如下
ScheduledThreadPoolExecutor executorService= (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10); System.out.println("延迟5秒执行"); for(int i=0;i<10;i++) { executorService.schedule(new MyThread(i+""), 5, TimeUnit.SECONDS); }
newScheduledThreadPool 主要用于执行定时任务和具有固定周期的重复任务。
A.scheduleAtFixedRate 一定频率周期重复执行任务
scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)
四个参数,Runnable command是要执行的线程任务对象,initialDelay是最开始要延迟执行的时间,period是每隔多久要执行一次任务,unit是时间的单位
ScheduledThreadPoolExecutor executorService= (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10); System.out.println("延迟5秒执行"+new Date()); executorService.scheduleAtFixedRate(new MyThread("1"), 5, 10, TimeUnit.SECONDS);
①以上设置为:MyThread的执行时间为2秒,开始之前,延迟5秒执行,之后,每隔10秒执行一次。结果如下:
可以看到
1。最开始线程任务并没有马上执行,而是延迟了5秒执行。
2。每隔10秒执行一次,是俩次任务的开始时间间隔了10秒,而不是前一个线程完成之后,等待10秒再执行下一次任务。
②设置MyThread的执行时间为15秒,其他设置不变,也就是仍然延迟5秒执行,然后每隔10秒执行一个。结果如下:
可以看到两次任务开始的间隔时间有了变化,不是设置的间隔10秒执行一次,而是每隔15秒执行了一次。
综上:
1。scheduleAtFixedRate 设置执行间隔,是指线程任务A的开始执行时间,到下次线程任务A的开始执行时间
2。当任务A执行时间(15秒)大于 指定的间隔(10秒),下次任务A的开始的时间,是等待执行结束后(15秒后)再执行
3。小于的话,就不用说了,两次任务开始的间隔为 设置的间隔(10秒)
可以想象,如果想在每天的同一时间比如中午12点执行任务,
1。先计算当前时间到中午12点的时间有多长,首次执行,可以延长这个时间执行任务
2。设置间隔时间为24小时,那么下一个中午12点,就会执行此任务
3。假设每次这个任务执行都需要25小时才能完成,那么下次执行任务的时间为第二天中午1点,然后每天都会推后一小时,第三天中午2点,第四天中午3点。。。。
B. scheduleWithFixedDelay 一定的延迟周期重复执行
①设置MyThread 执行时间为2秒,开始之前,延迟5秒执行,之后,每隔10秒执行一次。
ScheduledThreadPoolExecutor executorService= (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10); System.out.println("延迟5秒执行"+new Date()); executorService.scheduleWithFixedDelay(new MyThread("1"), 5, 10, TimeUnit.SECONDS);
结果如下:
可以看到,间隔10秒是以上次任务结束开始计时间隔的
②设置MyThread 执行时间为15秒,开始之前,延迟5秒执行,之后,每隔10秒执行一次。结果如下:
可以看到,仍然是以上次任务结束时间为准,开始计算时间间隔
综上:scheduleWithFixedDelay 是上一次任务执行完后,开始计时时间间隔
- java 四种线程池
- Java四种线程池
- Java 四种线程池
- java四种线程池
- Java四种线程池
- Java四种线程池
- java 四种 线程池
- Java 四种线程池
- java四种线程池
- java四种线程池
- JAVA四种线程池
- java四种线程池
- Java 四种线程池
- Java四种线程池
- 【Java线程】Java线程池ExecutorService四种详解
- Java四种线程池的使用
- Java四种线程池的使用
- Java四种线程池的使用
- Python基础语法之字符串
- Java多线程——线程同步
- 2017年8月10日---阶段性工作总结(事件驱动)
- vue-router中注意单词
- select函数
- Java四种线程池
- Mac OS 下用Tex Shop 进行中文排版
- L79系列三端稳压管管脚连线说明
- 音视频直播技术--SurfaceView、GLSurfaceView与TextureView
- Langton蚂蚁——简单的元胞自动机(2)
- C++ 快速学习(一)
- 11. Container With Most Water
- MYSQL启动报1067错误(测试了不好用??)
- 内核源码阅读(二)进程复制