关系经济人类预测化学自然
中准网
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

JAVA线程池的一些琐事

2月6日 菩提门投稿
  焦点:为什么要有线程池?java如何创建线程池,区别是什么?几个思考的问题?2。为什么要有线程池?
  多线程特点:资源占用多默认一个线程的栈1M(Xss可配)(note:堆外,栈溢出)需要上下文切换cpu切换之前的状态存储(pc,寄存器等)
  线程池(资源池)都是为了解决一个主要问题:创建线程(资源)和销毁线程(资源)的成本,比维护线程(资源)池的成本高。
  延伸可解决的问题:限制程序对资源无限申请可管理,可监控
  对比:协程(内存8k),线程成本更高,线程池就成了常用手段之一3。java如何创建线程池?
  创建线程池的方法:newThreadPoolExecutor()Executors。newXXXX()
  Executors。newXXXX()是对newThreadPoolExecutor()提供的封装3。1ThreadPoolExecutor
  java中的线程池ThreadPoolExecutorpublicThreadPoolExecutor(intcorePoolSize,核心线程数intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueRunnableworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler){if(corePoolSize0maximumPoolSize0maximumPoolSizecorePoolSizekeepAliveTime0L){if(workQueue!nullthreadFactory!nullhandler!null){this。corePoolSizecorePoolSthis。maximumPoolSizemaximumPoolSthis。workQueueworkQthis。keepAliveTimeunit。toNanos(keepAliveTime);this。threadFactorythreadFthis。}else{thrownewNullPointerException();}}else{thrownewIllegalArgumentException();}}publicvoidexecute(Runnablecommand){if(commandnull){thrownewNullPointerException();}else{intcthis。ctl。get();if(workerCountOf(c)this。corePoolSize){当前worker数量corePoolSize,将添加一个worker线程来工作if(this。addWorker(command,true)){}cthis。ctl。get();}if(isRunning(c)this。workQueue。offer(command)){当前worker数量corePoolSize,将多余的任务放到worker队列中intrecheckthis。ctl。get();if(!isRunning(recheck)this。remove(command)){this。reject(command);}elseif(workerCountOf(recheck)0){this。addWorker((Runnable)null,false);}}elseif(!this。addWorker(command,false)){如果使用worker队列放不下,且也无法增加worker线程的数量(达到maximumPoolSize)了,就执行拒绝this。reject(command);}}}添加worker线程(coretrue:占用corePoolSize线程的名额;corefalse:占用maximumPoolSizecorePoolSize线程的名额)privatebooleanaddWorker(RunnablefirstTask,booleancore){}
  BlockingQueue有什么?ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO(先进先出)原则对元素进行排序。LinkedBlockingQueue:一个基于链表结构的无界阻塞队列(capacity2147483647),此队列按FIFO(先进先出)排序元素,吞吐量通常要高于ArrayBlockingQueue。SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue。PriorityBlockingQueue:一个具有优先级的无界阻塞队列(capacity2147483647),内部使用PriorityQueue。
  RejectedExecutionHandler有什么?ThreadPoolExecutor。AbortPolicy如果元素添加到线程池中失败,则直接抛运行时异常RejectedExecutionException(默认)ThreadPoolExecutor。DiscardPolicy如果元素添加线程池失败,则放弃,不抛异常。ThreadPoolExecutor。CallerRunsPolicy如果元素添加线程池失败,则主线程自己来运行任务。ThreadPoolExecutor。DiscardOldestPolicy如果元素添加线程池失败,会将队列中最早的元素删除之后,再尝试添加,一直重复成功为止。3。2Executors。newXXXX()
  这些都啥区别?java。util。concurrent。ExecutorsnewFixedThreadPool(int)coresize和maxsize一样大,无界队列publicstaticExecutorServicenewFixedThreadPool(intnThreads){returnnewThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit。MILLISECONDS,newLinkedBlockingQueue());}publicstaticExecutorServicenewFixedThreadPool(intnThreads,ThreadFactorythreadFactory){returnnewThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit。MILLISECONDS,newLinkedBlockingQueue(),threadFactory);}java。util。concurrent。ExecutorsnewCachedThreadPool()无队列,来一个任务,开一个线程,直到oom(内部逻辑,2147483647之后就手动oom异常)publicstaticExecutorServicenewCachedThreadPool(){returnnewThreadPoolExecutor(0,2147483647,60L,TimeUnit。SECONDS,newSynchronousQueue());}publicstaticExecutorServicenewCachedThreadPool(ThreadFactorythreadFactory){returnnewThreadPoolExecutor(0,2147483647,60L,TimeUnit。SECONDS,newSynchronousQueue(),threadFactory);}java。util。concurrent。ExecutorsnewSingleThreadExecutor()core和max都是1,无界队列publicstaticExecutorServicenewSingleThreadExecutor(){returnnewExecutors。FinalizableDelegatedExecutorService(newThreadPoolExecutor(1,1,0L,TimeUnit。MILLISECONDS,newLinkedBlockingQueue()));}publicstaticExecutorServicenewSingleThreadExecutor(ThreadFactorythreadFactory){returnnewExecutors。FinalizableDelegatedExecutorService(newThreadPoolExecutor(1,1,0L,TimeUnit。MILLISECONDS,newLinkedBlockingQueue(),threadFactory));}java。util。concurrent。ExecutorsnewScheduledThreadPool(int)定时执行的线程池publicstaticScheduledExecutorServicenewSingleThreadScheduledExecutor(){returnnewExecutors。DelegatedScheduledExecutorService(newScheduledThreadPoolExecutor(1));}publicstaticScheduledExecutorServicenewSingleThreadScheduledExecutor(ThreadFactorythreadFactory){returnnewExecutors。DelegatedScheduledExecutorService(newScheduledThreadPoolExecutor(1,threadFactory));}publicstaticScheduledExecutorServicenewScheduledThreadPool(intcorePoolSize){returnnewScheduledThreadPoolExecutor(corePoolSize);}publicstaticScheduledExecutorServicenewScheduledThreadPool(intcorePoolSize,ThreadFactorythreadFactory){returnnewScheduledThreadPoolExecutor(corePoolSize,threadFactory);}java。util。concurrent。ExecutorsnewWorkStealingPool(int)支持工作窃取的线程池publicstaticExecutorServicenewWorkStealingPool(intparallelism){returnnewForkJoinPool(parallelism,ForkJoinPool。defaultForkJoinWorkerThreadFactory,(UncaughtExceptionHandler)null,true);}publicstaticExecutorServicenewWorkStealingPool(){returnnewForkJoinPool(Runtime。getRuntime()。availableProcessors(),ForkJoinPool。defaultForkJoinWorkerThreadFactory,(UncaughtExceptionHandler)null,true);}4。几个思考的问题4。1核心线程怎么保活
  使用阻塞队列(这就是为什么就算空队列,也一定要传入workQueue这个参数)。getTask是每个worker线程,获取自己要执行的任务。
  4。2怎么实现keepAliveTime的
  同上blockQueue的poll4。3ScheduledExecutorService怎么实现任务定时执行
  构造函数:coresize传入,maxsize2147483647,workQueueScheduledThreadPoolExecutor。DelayedWorkQueue()publicScheduledThreadPoolExecutor(intcorePoolSize){super(corePoolSize,2147483647,10L,TimeUnit。MILLISECONDS,newScheduledThreadPoolExecutor。DelayedWorkQueue());}publicScheduledThreadPoolExecutor(intcorePoolSize,ThreadFactorythreadFactory){super(corePoolSize,2147483647,10L,TimeUnit。MILLISECONDS,newScheduledThreadPoolExecutor。DelayedWorkQueue(),threadFactory);}publicScheduledThreadPoolExecutor(intcorePoolSize,RejectedExecutionHandlerhandler){super(corePoolSize,2147483647,10L,TimeUnit。MILLISECONDS,newScheduledThreadPoolExecutor。DelayedWorkQueue(),handler);}publicScheduledThreadPoolExecutor(intcorePoolSize,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler){super(corePoolSize,2147483647,10L,TimeUnit。MILLISECONDS,newScheduledThreadPoolExecutor。DelayedWorkQueue(),threadFactory,handler);}
  ScheduledThreadPoolExecutor。DelayedWorkQueue:相当于DelayQueue和PriorityQueue的结合体。(权重是下次执行的时间),无界队列
  delayQueue是什么?是一个BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。classMyDelayedTaskimplementsDelayed{privateSprivatelongstartSystem。currentTimeMillis();publicMyDelayedTask(Stringname,longtime){this。this。}需要实现的接口,获得延迟时间,0的时候,就表示可以用了OverridepubliclonggetDelay(TimeUnitunit){returnunit。convert((starttime)System。currentTimeMillis(),TimeUnit。MILLISECONDS);}用于延迟队列内部比较排序当前时间的延迟时间比较对象的延迟时间OverridepublicintcompareTo(Delayedo){MyDelayedTasko1(MyDelayedTask)o;return(int)(this。getDelay(TimeUnit。MILLISECONDS)o。getDelay(TimeUnit。MILLISECONDS));}OverridepublicStringtoString(){returnMyDelayedTask{namename,timetime};}}
  常用方法:
  注意:execute并不会实现延迟效果(因为execute是线程池通用方法,仍然依赖先core,后queue,再max,最后reject)
  问题:schedule,scheduleAtFixedRate,scheduleWithFixedDelay是如何实现延迟的?publicScheduledF?schedule(Runnablecommand,longdelay,TimeUnitunit){if(command!nullunit!null){RunnableScheduledFutureVoidtthis。decorateTask((Runnable)command,newScheduledThreadPoolExecutor。ScheduledFutureTask(command,(Object)null,this。triggerTime(delay,unit),sequencer。getAndIncrement()));根据任务(command)构建一个延迟任务对象this。delayedExecute(t);延迟执行这个任务}else{thrownewNullPointerException();}}privatevoiddelayedExecute(RunnableScheduledF?task){if(this。isShutdown()){this。reject(task);}else{super。getQueue()。add(task);直接将任务加到workQueue里面,所以ScheduledThreadPoolExecutor是先queue,再core,再max,在rejectif(!this。canRunInCurrentRunState(task)this。remove(task)){task。cancel(false);}else{this。ensurePrestart();}}}
  scheduleAtFixedRate和scheduleWithFixedDelay流程一样,但是延迟任务对象构造出来的不一样4。4ForJoinPool4。4。1什么是forkjoin什么是mapreduce
  forkjoin和mapreduce都是分治的思想。
  举例子:forkjoin:123456((123)(456))(((12)(3))((45)(6)))递归拆分拆分之后块与块之间仍然有联系单机mapreduce:123456sum((12),(56),(34))拆分一次,随机拆分,拆分成目标大小的块即可reduce也是随机的,块与块之间不存在联系分布式
  forkjoin模式:
  4。4。2什么是workstaling
  核心思想:workstealing工作窃取
  充分利用线程进行并行计算,减少线程间的竞争(在某些情况下还是会存在竞争,比如双端队列里只有一个任务时)。4。4。3JavaForkJoinPool
  在ForkJoinPool中,线程池中每个工作线程(ForkJoinWorkerThread)都对应一个任务队列(WorkQueue),工作线程优先处理来自自身队列的任务(LIFO或FIFO顺序,参数mode决定),然后以FIFO的顺序随机窃取其他队列中的任务。
  具体思路如下:每个线程都有自己的一个WorkQueue,该工作队列是一个双端队列。队列支持三个功能push、pop、pollpushpop只能被队列的所有者线程调用,而poll可以被其他线程调用。划分的子任务调用fork时,都会被push到自己的队列中。默认情况下,工作线程从自己的双端队列获出任务并执行。当自己的队列为空时,线程随机从另一个线程的队列末尾调用poll方法窃取任务。
  4。4。4java怎么使用ForkJoinPool
  ForkJoin框架主要包含三个模块:任务对象:ForkJoinTask(包括RecursiveTask、RecursiveAction和CountedCompleter)执行ForkJoin任务的线程:ForkJoinWorkerThread线程池:ForkJoinPool
  ForkJoinPool只接收ForkJoinTask任务(在实际使用中,也可以接收RunnableCallable任务,但在真正运行时,也会把这些任务封装成ForkJoinTask类型的任务),RecursiveTask是ForkJoinTask的子类,是一个可以递归执行的ForkJoinTask,RecursiveAction是一个无返回值的RecursiveTask,CountedCompleter在任务完成执行后会触发执行一个自定义的钩子函数。importjava。util。concurrent。RecursiveTpublicclassCountTaskextendsRecursiveTaskLong{publicCountTask(intstart,intend,intlimit){this。this。this。}OverrideprotectedLongcompute(){longsum0;if(endstartlimit){for(i){}}else{intmid(startend)2;CountTaskcountTask1newCountTask(start,mid,limit);CountTaskcountTask2newCountTask(mid1,end,limit);countTask1。fork();countTask2。fork();Longresult1countTask1。join();Longresult2countTask2。join();sumresult1result2;}}}publicclassMain{publicstaticvoidmain(String〔〕args){longstartSystem。currentTimeMillis();ForkJoinPoolforkJoinPoolnewForkJoinPool();CountTaskcountTasknewCountTask(1,1000000,5);LonginvokeforkJoinPool。invoke(countTask);longendSystem。currentTimeMillis();System。out。println(invoke,(endstart));}}500000500000,126
  提交任务的区别:invoke()会等待任务计算完毕并返回计算结果;execute()是直接向池提交一个任务来异步执行,无返回结果;submit()也是异步执行,但是会返回提交的任务,在适当的时候可通过task。get()获取执行结果。4。4。5ForkJoinPool的核心参数核心线程数:默认线程数Runtime。getRuntime()。availableProcessors()最小线程数1默认Runtime。getRuntime()。availableProcessors(),cpu线程数最大32767keepAlive60000mspublicForkJoinPool(){this(Math。min(32767,Runtime。getRuntime()。availableProcessors()),defaultForkJoinWorkerThreadFactory,(UncaughtExceptionHandler)null,false,0,32767,1,(Predicate)null,60000L,TimeUnit。MILLISECONDS);}
  队列大小:
投诉 评论 转载

中科院在木材腐烂的机制方面取得重要进展尽管木质纤维素残基的生物转化对森林土壤营养物质的储存至关重要,但木材腐烂的地域性以及与地下微生物群落组成和土壤化学性质相互作用的机制尚不明确。本研究对白腐和棕腐木屑的成分进行了……陈晓高调庆生老婆凌晨送惊喜!夫妻俩公开秀恩爱,陈晓穿搭却太土陈晓和陈妍希这对明星夫妻真的是太让人羡慕了,虽然夫妻俩很少公开秀恩爱,但是俩人每一次的同框都能让大家看出她们满满的爱意,不久前是陈晓的生日,作为妻子的陈妍希更是在凌晨卡点晒照为……国内氢能源的先驱,试驾丰田限量50台的Mirai当下,如果说到新能源,相信大家想到的都会是纯电动,但实际上氢能源,同样作为新能源也在其他国家发热发亮当中,而其中之一那就是丰田了。如今,丰田也将技术渐趋成熟的氢能源产品,第二代……研究揭示蛋氨酸分子机制科学调控肉鸭脂肪生长中国农业科学院北京畜牧兽医研究所水禽育种与营养创新团队研究揭示了蛋氨酸调控北京鸭脂肪沉积的分子机制,为合理使用蛋氨酸,促进肉鸭高效健康养殖提供了理论依据。相关研究成果发表在《畜……乒乓球原标题:乒乓球WTT新加坡大满贯:梁靖崑晋级四强3月17日,卡尔松在比赛中。当日,在新加坡举行的世界乒乓球职业大联盟(WTT)新加坡大满贯男单四分之一决赛中,中国选……香港经济2023年将强势回归据彭博新闻社网站1月9日报道,在经历了去年的收缩之后,香港经济今年将强势回归,甚至可能逾10年来增速首次超过竞争对手新加坡。调查显示,随着香港加速与中国内地和世界各地实现……象棋杀棋练习六步杀45象棋杀棋练习六步杀,适合初、中级象棋爱好者,天天象棋业6以下水平可以练练。没有特别说明的都是红先胜,基本上都是连将杀。上期答案,仅供参考,部分棋局并非唯一解。1。马……30分!26分!入选男篮遭群嘲,宏远小丑鸭今成超级大腿,狠狠如果要球迷评选最近两年入选中国男篮国家队争议最多的球员,那么广东宏远的徐杰,应该可以排进前三。作为宏远黑白矮组合中敬陪末座的存在,徐杰一开始就不被大家看好。身材矮小、对抗吃亏、……泰国华裔富婆庆56岁,穿露脐装小腹毫无赘肉,定制爱马仕包当背当地时间3月21日,在社交媒体上颇为知名的泰国华裔富婆伍伦盼(NualphanLamsam),迎来了56岁生日。也许是为了力证自己青春气息不减,这位向来走端庄雍容路线的保险公司……JAVA线程池的一些琐事焦点:为什么要有线程池?java如何创建线程池,区别是什么?几个思考的问题?2。为什么要有线程池?多线程特点:资源占用多默认一个线程的栈1M(Xss可配)(note:堆外……被上海女生圈粉了裙不上膝,鞋不带跟,美得让人挪不开眼最近比较流行一个话题当博主穿搭回归现实的时候,其实有的博主还是很美的,但是大多数博主的穿搭看起来多少都有点拉跨,所以要说到能直接照搬的穿搭,还是得看普通人的街拍。上海作为……山寨机刷新认知名叫Phone14ProMax,抄袭小米Civ正常情况下,iPhone14系列将在今年9月中旬发布,距今还有一个半月左右时间,不少粉丝等得望眼欲穿。此时有网友发现,某电商平台意外上架Phone14ProMax,正面搭载挖孔……
R57600X670E吹雪搭台,5款显卡实测生化危机4重置版蒙脱石散怪象太阳球星保罗跟卡戴珊热血传奇狂暴传奇新服开启大师试炼,累计试炼值,解锁终极豪礼濑户内乔佐乔,一座尽享山海美景的酒庄CBA广东队三大消息徐杰年薪翻倍,新外援归队,张皓嘉重点培养郭艾伦离队蝴蝶效应!高诗岩接近重返辽宁,山东遭重创贾宗洋,我们为你感到骄傲首播口碑爆棚,狂追六集不过瘾,网友真正的国产刑侦大剧来了哈姆康利展现出的篮球水平太了不起了我以为我在看灰熊打球呢男人结扎和女人结扎有什么区别?看完后,这几个好处女人真没法比美550名女性集体起诉优步!称遭司机绑架性侵殴打跟踪
人长期饮用软水后果世上没有白天黑夜之分的地方当地取消了24小时制吃饭睡觉全凭感东方卫视秋晚强势破圈!晚会好看实力更漂亮蒜苗观察日记倔强甜心什么时间上映倔强甜心影片信息介绍新手微商怎么找客源怎么找货源得了口周皮炎如何治疗回廊落月(14)对了月亮,更容易想念幼儿园春节活动教案过年了想100成功,需200努力行星状星云指的什么?行星状星云重要特点40岁波尔成为世乒赛史上最年长奖牌选手2024巴黎有望七战奥

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州