游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

多线程(二)Executors

  上篇文章,我们讲解了通过Thread和Runnable使用线程的方法,并且演示了如何创建一个线程并启动,今天我们来聊一聊多线程中的线程池。一、为什么要使用线程池
  我们使用多线程的一个一般步骤是:先创建一个线程,然后线程执行线程任务,线程任务执行完毕后,线程会被销毁。
  但是线程的创建和销毁是比较耗费资源的。在高并发场景之下,如果需要开启大量的线程,而每个线程它执行任务所需的时间很短的情况下,那么线程的频繁的创建和销毁就会成为性能的瓶颈。所以线程池应运而生。线程池的主要功能就是可以用来管理线程,让线程能够复用,避免重复创建线程,并且我们可以根据需求,合理配置线程池中的各种参数。
  通俗地说就是当有任务的时候,我们就通过线程池来获取线程,任务完成后再把线程归还给线程池供其他任务使用。线程池会帮我们维护指定数量的活跃可用线程,避免了重复创建造成的资源浪费。二、Executors用法
  Java中提供了Executors类,本身是个工厂模式,相当于就是一个线程池工厂(注意是线程池工厂,不是线程工厂),里边提供了多种不同的线程池可供我们直接使用。2。1newSingleThreadExecutor
  创建一个单线程的线程池。创建线程池的方法都是Executors中的静态方法,我们可以直接使用类名调用就能获取,得到线程池的类型为ExecutorService,可以调用里面的submit方法,传入Runnable类型的线程任务来执行。
  我们通过案例给大家演示一下:packagecom。lsqingfeng。action。knowledge。multithread。pools;importjava。util。concurrent。ExecutorService;importjava。util。concurrent。Executors;importjava。util。concurrent。TimeUnit;className:SingleThreadExecutorDemodescription:author:sh。Liudate:2022040714:00publicclassSingleThreadExecutorDemo{publicstaticvoidmain(String〔〕args){获取一个单线程的线程池:ExecutorServicesingleThreadExecutorExecutors。newSingleThreadExecutor();给定两个线程任务:Runnabler1(){try{TimeUnit。SECONDS。sleep(2);}catch(InterruptedExceptione){e。printStackTrace();}System。out。println(Thread。currentThread()。getName()正在执行线程任务1);};Runnabler2(){System。out。println(Thread。currentThread()。getName()正在执行线程任务2);};将线程任务提交给先线程池,通过线程池执行任务,就不需要我们自己创建线程了,只关注任务即可查看结果:任务2等待任务1完成后才执行,说明只有一个线程可用singleThreadExecutor。submit(r1);singleThreadExecutor。submit(r2);}}
  执行结果:
  pool1thread1正在执行线程任务1(2s后)
  pool1thread1正在执行线程任务2
  看到它们线程的名称都是一样的。并且根据执行的时间也可以看出,两个线程任务是被同一个线程执行的。2。2newFixedThreadPool
  创建一个指定数量的线程池。我们可以通过传入参数,来设置该线程池中有多少个活跃线程。当线程池中有可用线程池,提交的任务就会立即执行,如果当前线程中没有可用线程,则会将任务放入到一个队列中,直到有线程可用。我们还是通过代码来演示。packagecom。lsqingfeng。action。knowledge。multithread。pools;importjava。util。concurrent。ExecutorService;importjava。util。concurrent。Executors;importjava。util。concurrent。TimeUnit;className:FixThreadExecutorDemodescription:author:sh。Liudate:2022040714:42publicclassFixThreadExecutorDemo{publicstaticvoidmain(String〔〕args){获取FixThread线程池:指定活跃线程数量2ExecutorServiceexecutorServiceExecutors。newFixedThreadPool(2);创建两个任务:给定一个线程任务:Runnabler1(){try{睡两秒TimeUnit。SECONDS。sleep(2);}catch(InterruptedExceptione){e。printStackTrace();}System。out。println(Thread。currentThread()。getName()正在执行线程任务1);};Runnabler2(){System。out。println(Thread。currentThread()。getName()正在执行线程任务2);};将任务已提交给线程池两次:executorService。submit(r1);executorService。submit(r1);再提交任务2,看任务2是否是在2秒后执行,如果是,说明没有可用线程,只能等2秒后才有线程能用executorService。submit(r2);}}
  结果:
  pool1thread1正在执行线程任务1(2s后运行的)
  pool1thread2正在执行线程任务1pool1thread1正在执行线程任务2
  我们继续验证,把活跃数量改为3,这个时候,看看任务2是否会先执行。
  pool1thread3正在执行线程任务2pool1thread2正在执行线程任务1pool1thread1正在执行线程任务1
  果然,此时任务2就先执行了,因为有活跃线程可用。
  注意:大家在运行上述代码的时候,打印结果后程序还没有结束,这是因为线程池就是一直活跃在等待接收任务的状态,所以程序不会结束,要想结束我们需要调用shutdown方法将线程池关闭。2。3newCachedThreadPool
  创建一个可缓存的线程池。这个线程池的特点是不对线程的数量做限制,只要有线程任务没有线程来处理,就会创建一个线程,同时该线程池有一个回收的功能,就是如果某个线程超过60秒还没有任务,就会被自动回收掉。packagecom。lsqingfeng。action。knowledge。multithread。pools;importjava。util。concurrent。ExecutorService;importjava。util。concurrent。Executors;importjava。util。concurrent。TimeUnit;className:CachedThreadPoolExecutorDemodescription:可缓存的线程连接池。无限大(完全取决于操作系统最大允许多少)超过60秒自动回收author:sh。Liudate:2022040716:04publicclassCachedThreadPoolExecutorDemo{publicstaticvoidmain(String〔〕args){创建一个可缓存的线程连接池ExecutorServicecachedThreadPoolExecutors。newCachedThreadPool();创建线程任务Runnabler1(){try{TimeUnit。SECONDS。sleep(2);}catch(InterruptedExceptione){e。printStackTrace();}System。out。println(Thread。currentThread()。getName()正在执行任务);};提交任务cachedThreadPool。submit(r1);cachedThreadPool。submit(r1);cachedThreadPool。submit(r1);}}
  执行结果:
  三个线程都是不同的代表每次都会创建新的。因为没获取到可用的,就会创建新的。
  注意这个红灯,60秒钟后会熄灭。因为执行完任务后,会自动回收60秒内没被使用的线程。2。4newScheduledThreadPool
  创建一个可用于执行周期性任务的线程池。我们前面使用多线程执行的任务都是一次性的。但是有的时候我们希望可以周期性地执行任务,比如,每5分钟执行一次。这个时候,我们就可以使用周期性的线程池。
  这里要注意,返回的线程池类型和前面的有区别:ScheduledExecutorService代表周期性的线程池类型。packagecom。lsqingfeng。action。knowledge。multithread。pools;importjava。util。concurrent。Executors;importjava。util。concurrent。ScheduledExecutorService;importjava。util。concurrent。TimeUnit;className:ScheduledThreadPoolDemodescription:author:sh。Liudate:2022040716:40publicclassScheduledThreadPoolDemo{publicstaticvoidmain(String〔〕args){1。获取周期性线程池,传入核心线程的大小ScheduledExecutorServicescheduledExecutorServiceExecutors。newScheduledThreadPool(2);2。创建两个线程任务Runnabler1(){try{TimeUnit。SECONDS。sleep(2);}catch(InterruptedExceptione){e。printStackTrace();}System。out。println(Thread。currentThread()。getName()正在执行任务1);};Runnabler2(){System。out。println(Thread。currentThread()。getName()正在执行任务2);};3。线程池执行任务:注意调用方式:延迟三秒执行scheduledExecutorService。schedule(r1,3,TimeUnit。SECONDS);scheduledExecutorService。schedule(r1,3,TimeUnit。SECONDS);scheduledExecutorService。schedule(r2,2,TimeUnit。SECONDS);线程2秒后开始执行,每三秒执行一次。scheduledExecutorService。scheduleAtFixedRate(r2,2,3,TimeUnit。SECONDS);}}
  可以观察到,总共只有两个线程在工作,说明我们的设置是有效的。2。5newWorkStealingPool
  这是从JDK8开始新增的方法。代表创建了一个抢占式的线程池,底层是使用的ForkJoinPool来实现的。
  该线程池维护足以支持给定并行度级别的线程,并可以使用多个队列来减少争用。并行度级别对应于活动参与或可用于参与任务处理的最大线程数。实际的线程数可能会动态增长和收缩。newWorkStealingPool不能保证提交任务的执行顺序。
  ForkJoinPool是JDK7中引入的一种新的线程池,它同ThreadPoolExecutor一样,也实现了Executor和ExecutorService接口。它使用了一个无限队列来保存需要执行的任务,而线程的数量则是通过构造函数传入,如果没有向构造函数中传入希望的线程数量,那么当前计算机可用的CPU数量会被设置为线程数量作为默认值。
  ForkJoinPool的另外一个特性是它能够实现工作窃取(WorkStealing),在该线程池的每个线程中会维护一个队列来存放需要被执行的任务。当线程自身队列中的任务都执行完毕后,它会从别的线程中拿到未被执行的任务并帮助它执行。
  newWorkStealingPool会创建一个含有足够多线程的线程池,来维持相应的并行级别,它会通过工作窃取的方式,使得多核的CPU不会闲置,总会有活着的线程让CPU去运行。
  newWorkStealingPool的特点:可以传入线程的数量,不传入,则默认使用当前计算机中可用的cpu数量能够合理的使用CPU进行对任务操作(并行操作)适合使用在很耗时的任务中
  底层用的ForkJoinPool来实现的。ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个小任务分发到不同的cpu核心上执行,执行完后再把结果收集到一起返回。
  代码实现:packagecom。lsqingfeng。action。knowledge。multithread。pools;importjava。util。concurrent。ExecutorService;importjava。util。concurrent。Executors;importjava。util。concurrent。TimeUnit;className:WorkStealingPoolExecutorDemodescription:author:sh。Liudate:2022040717:17publicclassWorkStealingPoolExecutorDemo{publicstaticvoidmain(String〔〕args){创建线程池:不传参默认使用cpu个数创建ExecutorServiceexecutorServiceExecutors。newWorkStealingPool();创建任务:Runnabler1(){System。out。println(Thread。currentThread()。getName()正在执行任务);};提交任务:executorService。submit(r1);}}
  好了,关于Executors中的常用线程池我们就先介绍这么多。但其实在《阿里巴巴开发手册》中是不允许我们直接使用Executors中的工具类的,那么我们应该如何使用呢,下篇文章我们继续研究一个更重要的类ThreadPoolExecutor。如果文章对你有帮助,就给点个关注点个赞吧。
  更多内容欢迎关注公众号:一缕82年的清风

特斯拉全球6万辆汽车将被召回!二季度交付量下滑18,马斯克我每经编辑:王月龙,高涵据路透社7月3日报道,德国联邦运输管理处(KBA)表示,因自动紧急呼叫系统存在故障,将召回特斯拉(TSLA,股价681。79美元,市值7066。01……改造沙漠戈壁,再造中国,向沙漠和戈壁要土地改造沙漠戈壁,再造中国系列(第二篇)。中国待改造沙漠和戈壁的特点(一)中国待改造沙漠和戈壁的特点所有的未利用地,都在待改造的范畴之内。针对沙漠和戈壁的改造也是如此。如果沙……孩子好动,注意力不集中,是调皮还是真的出了问题?九江新闻网讯导致学习困难的最常见原因之一是注意力缺陷多动障碍(ADHD),也就是家长眼里的多动症。多动症可以说是最广为人知,却也被人误解最多的发育心理行为性问题及障碍。多……新五大发电集团的重组与发展8月份,中国华能、中国华电、中国大唐、国家电投、国家能源集团先后发布了2021年社会责任报告,新五大发电集团交出的成绩单再次成为各方关注焦点。据草根光伏统计,相较2020……在审判中,马斯克被定为骗子,让特斯拉普通股东损失了数百万美元周三,埃隆马斯克被描绘成一个无情地危害普通人储蓄的骗子,或者是一个善意的有远见的人,因为律师在一场以特斯拉收购为重点的审判中发表了开庭陈述,但该案件从未发生过。反对双方的……实拍最近兰州是这样!张掖路空了,马路不堵了张掖路空、西站十字空、公交空、地铁空、商场空、公园空,面对10月这一波疫情反弹,兰州人又一次被迫控在了小区、控在了单位、控在了家里。相信大家和我一样,每天早上醒来的第一件……T型台张若昀唐艺昕久违同框,给我种草了FENDI最让我感兴趣的一点是在诠释女性气质的同时探索功能实用性。KimJones虽然因为疫情大家无法前往现场助阵,但云看秀的嘉宾团还是热热闹闹。张若昀一身黑……态度强硬!5000万吓退其他下家,皇马皇储离队无望,明夏免费在夺得队史第14座欧冠冠军后,皇马也迎来了一波清洗热潮,贝尔,马塞洛和伊斯科3位皇马功勋球员都在这个夏窗离开了伯纳乌,同时三年前6400万欧元加盟的约维奇也被皇马免费送到佛罗伦……康洪撸起袖子加油干,为高标准高质量建设雄安新区添砖加瓦来源:【人民网】人民网雄安12月17日电(王红)两个资料柜,一张长条桌,一张折叠床在雄安国际酒店项目指挥部,一间由彩钢板搭建的简易房就是康洪近段时间的办公室及宿舍。……财说AIGC熄火了?视觉中国最近三个交易日股价跌幅超20的原记者杨马可编辑陈菲遐昨天KTV今天ICU是近期视觉中国(000681。SZ)股价走势的真实写照。在最近的三个交易日里,视觉中国股价累计下跌将近22。就在上周,……开放式创新助力企业变革创新之路你目前所在公司有经历过创新变革过吗?双十一前后排很长的队拿快递有没觉得人太多,好浪费时间啊?经过创新变革后,目前有些快递点采取用户自取自拿签收,避开人流量不用排长队,这样……银桥乳业真的要被卖了?这两天,陕西最大乳企银桥被河北君乐宝收购的消息,在网上疯传。关注度如此之高,重要原因在于,君乐宝在中国乳业排名第4,银桥位居20。若两家合二为一,对于行业的冲击和震动,委……
女乒四大主力排行,排名第一的不是陈梦,王艺迪有望赶超孙颖莎在东京奥运会结束后,中国女乒主教练李隼就明确表示,目前中国女乒已经完成了新老更替,这也意味着原来以丁宁、刘诗雯为绝对主力的中国女乒格局已经结束,形成了以陈梦、孙颖莎和王曼昱为绝……大衣嫂罕有发怒,疑似怒斥记者两面三刀,大声呵斥对方你走大衣哥一家与陈亚男之间的纠葛难道要反转?陈亚男离开朱家之后,风波并没有因此而终止,她与朱小伟之间到底发生了什么不可逆转的矛盾?是不是真的与榜一大哥有关系呢?陈亚男于近日接受的采……全球人口将突破80亿,以现在的增长速度,本世纪末或达到地球极在今天,全球人口即将突破80亿,很多人却不知道,在7万多年前,由于一次超级火山爆发,人类人口降到历史低点,差点灭绝。距今75000年前,位于印尼达蜡岛上一座名为多巴的超级……6种让你贫血的食物,你吃过几种?婴幼儿是容易贫血的群体,当发现贫血时,要在饮食上多多注意,注意给宝宝补铁补血。贫血要多吃6种食物:铁,被称为血液里的矿物质,是构成血液里血红蛋白的重要组成部分,人体……手机拍摄强or相机拍摄强xiaomi11Ultra原生拍摄本身手机拍摄和相机拍摄是两个不可同日而语的事情,但是科技的不断创新,使得这两件事又貌似有些关系。随着生产工艺的精进,手机和相机都在……诗和远方文:霜雪飞在我小时候,太阳升起的地方是山尖太阳落下的地方还是山尖一边是东一边是西妈妈说:儿啊,等你长大了就翻过太阳升起的那座山,到外面……继刘涛起诉造谣者散播不实婚变消息,另一边王珂却默默取关老婆前不久在刘涛王珂被传离婚消息后,刘涛工作室也在第一时间发文辟谣,并且对造谣者进行起诉,追究其法律责任。对于两人关系也一直众说纷纭。有人觉得二人就是夫妻间的相濡以沫平……在海底被发现价值连城的宝藏(一)海洋是一个广阔的空间,覆盖了地球的大部分地区。早在飞机在世界各地飞行之前,轮船是唯一的旅行方式。对许多人来说,在船上工作就是一件让人羡慕的工作。不是每艘船都能安全回家,有……1961年1月31日黑猩猩哈姆进入太空自20世纪50年代末以来,美国和苏联之间的太空竞赛一直在升温,苏联人已经将狗送入轨道,证明哺乳动物可以在太空中生存。但是美国宇航局想证明人类可以在零重力下执行任务,于是太空黑猩……脱口秀大会4迄今为止最好的一期,笑点密集,还有现场求婚看《脱口秀大会》第四季半决赛下半场,用两个字形容,那就是精彩!这应该是迄今为止,第四季中最好看的一期节目了。第一个登场的是四季老人庞博,颜值还是抗打,表演还是稳定,文本还是……距离魅友大会2022召开不到两天魅族19系列外观设计或来自这随着距离魅族科技官宣的将于12月23日14:00在珠海举办的新一届魅友大会2022已经不到两天了,近日,越来越多的媒体、达人以及报名参会的魅友展示出了自己收到的邀请函以及车票截……美媒施罗德拒绝买断加盟湖人,他不想为詹姆斯和威少背锅全明星周末结束之后,NBA即将开始赛季的下半程。在最近几天,很多球队都开始在买断市场上物色球员。费城为了给恩比德减轻压力,在今天签下了中锋考利斯坦;雄鹿队签下了篮网队裁掉的后卫……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网