Java四种线程池

来源:互联网 发布:不错吧源码 编辑:程序博客网 时间:2024/06/07 01:40

遇到了上传图片的功能,之前由于上传图片数量少,没有使用线程池,现在要最多支持30张图片上传,再像之前上传多少张图片,就开启多少个线程就有点行不通了,所以使用了线程池。

一、线程池 ExecutorService的基本使用

  1. 创建线程池对象
//使用定长类线程池newFixedThreadPool的方式演示 ExecutorService fixedThreadPool= Executors.newFixedThreadPool(3);
  1. 执行
    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 是上一次任务执行完后,开始计时时间间隔

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 c牌一次扣12分怎么办 超速罚500扣12分怎么办 高速超速记3分怎么办 高速超速记12分怎么办 过江隧道关闭了怎么办 高速限速60超了怎么办 超速扣了12分怎么办 上海 12分扣完了怎么办 狗抓伤只淌白沫怎么办 刑事案件法院迟迟不判决怎么办 法院判决书下来了没钱赔偿怎么办 被起诉开庭不去怎么办 地道塌陷造成房屋倒塌怎么办 海外看不了b站怎么办 最近脸胖了好多怎么办 最近胖了好多怎么办啊? 很瘦的人手胖怎么办 长得丑不敢相亲怎么办 abs抱死发不动了怎么办 qq飞车手游车到期了改装怎么办 育碧下载游戏慢怎么办 豹纹守宫鼻子还有个残皮怎么办 睫角守宫断尾怎么办 定金发票弄丢了怎么办 xp电脑显示输入不支持怎么办 月子见风怎么办暴雪将 老氏电视机出现雪花点怎么办 飞利浦电视显示雪花片怎么办 电视无信号出雪花怎么办 电视打开都是雪花没有电视台怎么办 电视视频1无信号怎么办 新买的电视无信号怎么办 卫星有信号没有视频怎么办 户户通没有信号怎么办视频 雪花泥粘衣服上怎么办 遗产按份额处分判决后怎么办 宝马后驱车下雪天怎么办 宝马后驱车路滑怎么办 车子陷入泥地里怎么办 深圳居住证签注过期了怎么办 手机不能播放视频乱码了怎么办