¸ÃƪÎÄÕÂÒÔתÒÆÖÁgithub --
**Ŀ¼½á¹¹**
## Ò»¡¢Doug LeaÔÚJCP JSR-166 ר¼Ò×é³ÉԱ׫дµÄÎĵµ
## ¶þ¡¢JAVA8Ô´´úÂëÖÐ6ÖÖÏß³Ì״̬µÄ¶¨Òå
## Èý¡¢Ï̳߳صĺËÐIJÎÊý¼°¹¤×÷ÏêϸÁ÷³Ì addwork,runwork,Ï̻߳ØÊÕ....
## ËÄ¡¢Ï̳߳ØÏß³ÌÊýÁ¿¡¢¾Ü¾ø²ßÂÔ¡¢×èÈû¶ÓÁС¯ÅäÖÃÏê½â
## Î塢ʵսÏ̳߳ØÅäÖá¢À©Õ¹Ï̳߳ع¦ÄÜ
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52f8f270cf4b4363a2acebd816cf2a7f~tplv-k3u1fbpfcp-zoom-1.image)
**Ç°ÑÔµ¼¶Á**
ÓÉDoug LeaÔÚJCP JSR-166 *ר¼Ò×é³ÉÔ±µÄÐÖúÏÂ׫д ²¢ÒÑ·¢²¼µ½¹«¹²ÁìÓò Èç* http://creativecommons.org/publicdomain/zero/1.0/
Ò»¸ö**ExecutorService** ËüʹÓÿÉÄÜÊǶà¸ö³ØÏß³ÌÖеÄÒ»¸öÀ´Ö´ÐÐÿ¸öÌá½»µÄÈÎÎñ ͨ³£Ê¹ÓÃ**Executors**¹¤³§·½·¨¶ÔÆä½øÐÐÅäÖá£
Ï̳߳ؽâ¾öÁËÁ½¸ö²»Í¬µÄÎÊÌâ ÓÉÓÚ¼õÉÙÁËÿ¸öÈÎÎñµÄµ÷ÓÿªÏú ËüÃÇͨ³£ÔÚÖ´ÐдóÁ¿Òì²½ÈÎÎñʱÌṩ¸Ä½øµÄÐÔÄÜ ²¢ÇÒËüÃÇÌṩÁËÒ»Öְ󶨺͹ÜÀí×ÊÔ´ °üÀ¨Ïß³Ì µÄ·½·¨ ¸Ã×ÊÔ´ÔÚÖ´Ðм¯ºÏʱÏûºÄµôÁËÈÎÎñ¡£ ÿ¸öThreadPoolExecutor»¹Î¬»¤Ò»Ð©»ù±¾Í³¼ÆÐÅÏ¢ ÀýÈçÒÑÍê³ÉÈÎÎñµÄÊýÁ¿¡£
ΪÁËÔڹ㷺µÄÉÏÏÂÎÄÖÐÓÐÓà ¸ÃÀàÌṩÁËÐí¶à¿Éµ÷ÕûµÄ²ÎÊýºÍ¿ÉÀ©Õ¹ÐÔ¹Ò¹³¡£ µ«ÊÇ ½¨Òé³ÌÐòԱʹÓøü·½±ãµÄ**Executors**¹¤³§·½·¨**Executors.newCachedThreadPool** Îޱ߽çÏß³Ì³Ø ¾ßÓÐ×Ô¶¯Ï̻߳ØÊÕ **Executors.newFixedThreadPool** ¹Ì¶¨´óСµÄÏß³Ì³Ø ºÍ**Executors.newSingleThreadExecutor** µ¥¸öºǫ́Ïß³Ì ÕâЩ·½·¨¿ÉÒÔÔ¤ÏÈÅäÖÃÉèÖá£×î³£¼ûµÄʹÓó¡¾°¡£ ·ñÔò ÔÚÊÖ¶¯ÅäÖú͵÷Õû´ËÀàʱ ÇëʹÓÃÒÔÏÂÖ¸ÄÏ
ºËÐĺÍ×î´ó³Ø´óС
ThreadPoolExecutor½«¸ù¾ÝcorePoolSize Çë²Î¼û**getCorePoolSize** ºÍ**getCorePoolSize** Çë²Î¼û**getMaximumPoolSize** ÉèÖõĽçÏÞ×Ô¶¯µ÷Õû³Ø´óС Çë²Î¼ûgetPoolSize ¡£ µ±ÔÚ·½·¨execute(Runnable)Ìá½»ÐÂÈÎÎñ **²¢ÇÒÕýÔÚÔËÐеÄÏß³ÌÉÙÓÚcorePoolSizeÏß³Ìʱ ¼´Ê¹ÆäËû¹¤×÷Ï̴߳¦ÓÚ¿ÕÏÐ״̬ Ò²»á´´½¨Ò»¸öÐÂÏß³ÌÀ´´¦ÀíÇëÇó**¡£ Èç¹ûÔËÐеÄÏß³ÌÊý´óÓÚcorePoolSizeµ«Ð¡ÓÚmaximumPoolSize Ôò**½öÔÚ¶ÓÁÐÒÑÂúʱ²Å´´½¨ÐÂÏß³Ì**¡£ ͨ¹ý½«corePoolSizeºÍmaximumPoolSizeÉèÖÃΪÏàͬ ¿ÉÒÔ´´½¨¹Ì¶¨´óСµÄÏ̳߳ء£ ͨ¹ý½«maximumPoolSizeÉèÖÃΪһ¸ö±¾ÖÊÉϲ»ÊÜÏÞÖƵÄÖµ ÀýÈçInteger.MAX_VALUE ¿ÉÒÔÔÊÐí³ØÈÝÄÉÈÎÒâÊýÁ¿µÄ²¢·¢ÈÎÎñ¡£ ×îµäÐ굯 ºËÐĺÍ×î´ó³Ø´óС½öÔÚ¹¹ÔìʱÉèÖà µ«Ò²¿ÉÒÔʹÓÃsetCorePoolSizeºÍsetMaximumPoolSize¶¯Ì¬¸ü¸Ä¡£
°´ÐèÊ©¹¤
ĬÈÏÇé¿öÏ ÉõÖÁºËÐÄÏß³ÌÒ²½öÔÚÐÂÈÎÎñµ½´ïʱ²Å¿ªÊ¼´´½¨ºÍÆô¶¯ µ«ÊÇ¿ÉÒÔʹÓÃprestartCoreThread»òprestartAllCoreThreads·½·¨¶¯Ì¬µØ¸²¸ÇËü¡£ Èç¹ûʹÓ÷ǿնÓÁй¹Ôì³Ø Ôò¿ÉÄÜÒªÔ¤Æô¶¯Ï̡߳£
´´½¨ÐÂÏß³Ì
ʹÓÃThreadFactory´´½¨ÐÂÏ̡߳£ Èç¹ûûÓÐÁíÍâÖ¸¶¨ ÔòʹÓÃExecutors.defaultThreadFactory ¸ÃÏ̴߳´½¨µÄÏß³ÌÈ«²¿Î»ÓÚÏàͬµÄThreadGroup²¢ÇÒ¾ßÓÐÏàͬµÄNORM_PRIORITYÓÅÏȼ¶ºÍ·ÇÊØ»¤³ÌÐò״̬¡£ ͨ¹ýÌṩÆäËûThreadFactory ¿ÉÒÔ¸ü¸ÄÏ̵߳ÄÃû³Æ Ïß³Ì×é ÓÅÏȼ¶ ÊØ»¤³ÌÐò״̬µÈ¡£Èç¹ûÔÚͨ¹ýѯÎÊnewThread·µ»ØnullÀ´Ñ¯ÎÊThreadFactoryÎÞ·¨´´½¨Ïß³Ìʱ Ö´ÐÐÆ÷½«¼ÌÐøÖ´ÐÐ µ«¿ÉÄÜÎÞ·¨Ö´ÐÐÖ´ÐÐÈκÎÈÎÎñ¡£ Ïß³ÌÓ¦¾ßÓС° modifyThread¡± RuntimePermission ¡£ Èç¹ûʹÓøóصŤ×÷Ï̻߳òÆäËûÏ̲߳»¾ßÓдËÐí¿ÉȨ Ôò·þÎñ¿ÉÄܻή¼¶ ÅäÖøü¸Ä¿ÉÄܲ»»á¼°Ê±ÉúЧ ²¢ÇҹرճؿÉÄܱ£³ÖÔÚ¿ÉÄÜÖÕÖ¹µ«Î´Íê³ÉµÄ״̬¡£
±£»îʱ¼ä
Èç¹ûµ±Ç°³ØÖеÄÏß³ÌÊý³¬¹ýcorePoolSize Ôò¶àÓàµÄÏ߳̽«ÔÚ¿ÕÏÐʱ¼ä³¬¹ýkeepAliveTimeʱÖÕÖ¹ Çë²Î¼ûgetKeepAliveTime(TimeUnit) ¡£ µ±²»»ý¼«Ê¹ÓóØʱ ÕâÌṩÁËÒ»ÖÖ¼õÉÙ×ÊÔ´ÏûºÄµÄ·½·¨¡£ Èç¹û³ØÉÔºó±äµÃ¸ü¼Ó»îÔ¾ Ôò½«¹¹½¨ÐÂÏ̡߳£ Ò²¿ÉÒÔʹÓÃsetKeepAliveTime(long, TimeUnit)·½·¨**¶¯Ì¬¸ü¸Ä**´Ë²ÎÊý¡£ ʹÓÃLong.MAX_VALUE TimeUnit.NANOSECONDSµÄÖµLong.MAX_VALUEÓÐЧµØʹ¿ÕÏÐÏß³ÌÓÀÔ¶²»»áÔڹرÕ֮ǰÖÕÖ¹¡£ ĬÈÏÇé¿öÏ ½öµ±corePoolSizeÏß³ÌÊý¶àʱ ±£³Ö»î¶¯²ßÂÔ²ÅÊÊÓᣠµ«ÊÇ Ö»ÒªkeepAliveTimeÖµ²»ÎªÁã ·½·¨**allowCoreThreadTimeOut**(boolean)»¹¿ÉÓÃÓÚ½«´Ë³¬Ê±²ßÂÔÓ¦**ÓÃÓÚºËÐÄÏ̡߳£**
ÅŶÓ
ÈκÎBlockingQueue¾ù¿ÉÓÃÓÚ´«ÊäºÍ±£ÁôÌá½»µÄÈÎÎñ¡£ ´Ë¶ÓÁеÄʹÓÃÓë³Ø´óС½»»¥
Èç¹ûÕýÔÚÔËÐеÄÏß³ÌÉÙÓÚcorePoolSizeÏß³Ì ÔòÖ´ÐгÌÐò×ÜÊÇϲ»¶Ìí¼ÓÐÂÏß³Ì ¶ø²»ÊÇÅŶӡ£
Èç¹ûÕýÔÚÔËÐÐcorePoolSize»ò¸ü¶àÏß³Ì ÔòÖ´ÐгÌÐò×ÜÊǸüϲ»¶¶ÔÇëÇó½øÐÐÅÅ¶Ó ¶ø²»ÊÇÌí¼ÓÐÂÏ̡߳£
Èç¹ûÎÞ·¨½«ÇëÇó·ÅÈë¶ÓÁÐÖÐ Ôò½«´´½¨Ò»¸öÐÂÏß³Ì ³ý·Ç¸ÃÏ̳߳¬¹ýÁËmaximumPoolSize ÔÚÕâÖÖÇé¿öÏ ¸ÃÈÎÎñ½«±»¾Ü¾ø¡£
ÓÐÈýÖÖÒ»°ãµÄÅŶӲßÂÔ
Ö±½Ó½»½Ó¡£ ¶ÔÓÚ¹¤×÷¶ÓÁÐ Ò»¸öºÜºÃµÄĬÈÏÑ¡ÔñÊÇSynchronousQueue Ëü¿ÉÒÔ½«ÈÎÎñÒƽ»¸øÏß³Ì ¶ø²»±ØÁíÍâ±£ÁôËüÃÇ¡£ ÔÚÕâÀï Èç¹ûûÓÐÁ¢¼´¿ÉÓõÄÏß³ÌÀ´ÔËÐÐÈÎÎñ Ôò³¢ÊÔ½«ÆäÅŶӵij¢ÊÔ½«Ê§°Ü Òò´Ë½«¹¹ÔìÒ»¸öÐÂÏ̡߳£ ÔÚ´¦Àí¿ÉÄܾßÓÐÄÚ²¿ÒÀÀµÏîµÄÇëÇó¼¯Ê± ´Ë²ßÂÔ±ÜÃâÁËËø¶¨¡£ **Ö±½ÓÇл»Í¨³£ÐèÒªÎÞÏÞÖƵÄmaximumPoolSizesÒÔ±ÜÃâ¾Ü¾øÐÂÌá½»µÄÈÎÎñ**¡£ ·´¹ýÀ´ µ±Æ½¾ù¶øÑÔ ÃüÁî¼ÌÐøÒÔ±ÈÆä´¦ÀíËٶȸü¿ìµÄËٶȵ½´ïʱ Õâ¿ÉÄÜ»á**´øÀ´ÎÞÏÞÏß³ÌÔö³¤**µÄ¿ÉÄÜÐÔ¡£
ÎÞÏÞ¶ÓÁС£ ʹÓÃÎÞ½ç¶ÓÁÐ ÀýÈç ûÓÐÔ¤¶¨ÒåÈÝÁ¿µÄLinkedBlockingQueue ½«ÔÚËùÓÐcorePoolSizeÏ̷߳±Ã¦Ê±Ê¹ÐÂÈÎÎñÔÚ¶ÓÁÐÖеȴý¡£ Òò´Ë ½«½ö´´½¨corePoolSizeÏ̡߳£ Òò´Ë maximumPoolSizeµÄֵûÓÐÈκÎ×÷Óᣠµ±Ã¿¸öÈÎÎñÍêÈ«¶ÀÁ¢ÓÚÆäËûÈÎÎñʱ Õâ¿ÉÄÜÊÇÊʵ±µÄ Òò´ËÈÎÎñ²»»áÓ°Ïì±Ë´ËµÄÖ´ÐС£ ÀýÈç ÔÚÍøÒ³·þÎñÆ÷ÖС£ ¾¡¹ÜÕâÖÖÅŶӷ½Ê½¶ÔÓÚ**Ïû³ý¶ÌÔݵÄÇëÇóÍ»·¢ºÜÓÐÓÃ** µ«Ëü³ÐÈϵ±ÃüÁîƽ¾ù¼ÌÐøÒԱȴ¦ÀíËٶȸü¿ìµÄËٶȵ½´ïʱ ÎÞÏÞÖƵŤ×÷¶ÓÁÐÔö³¤ÊÇ¿ÉÄܵġ£
Óнç¶ÓÁС£ µ±ÓëÓÐÏÞµÄmaximumPoolSizesÒ»ÆðʹÓÃʱ Óнç¶ÓÁÐ ÀýÈçArrayBlockingQueue ÓÐÖúÓÚ·ÀÖ¹×ÊÔ´ºÄ¾¡ µ«µ÷ÓźͿØÖÆÆðÀ´»á¸ü¼ÓÀ§ÄÑ¡£ **¶ÓÁдóСºÍ×î´ó³Ø´óС¿ÉÄÜ»áÏ໥ÕÛÖÔ** ʹÓôó¶ÓÁкÍС³Ø¿ÉÒÔ×î´ó³Ì¶ÈµØ¼õÉÙCPUʹÓÃÂÊ ²Ù×÷ϵͳ×ÊÔ´ºÍÉÏÏÂÎÄÇл»¿ªÏú µ«»áµ¼ÖÂÈËΪµØ½µµÍÍÌÍÂÁ¿¡£ Èç¹ûÈÎÎñƵ·±×èÈû ÀýÈç Èç¹ûËüÃÇÊÜI / OÔ¼Êø Ôòϵͳ¿ÉÄÜÄܹ»°²ÅűÈÄúÔÏÈÔÊÐíµÄÏ̸߳ü¶àµÄʱ¼ä¡£ ʹÓÃС¶ÓÁÐͨ³£ÐèÒª¸ü´óµÄ³Ø´óС Õâ»áʹCPU·±Ã¦ µ«¿ÉÄÜ»áÓöµ½ÎÞ·¨½ÓÊܵĵ÷¶È¿ªÏú ÕâÒ²»á½µµÍÍÌÍÂÁ¿¡£
±»¾Ü¾øµÄÈÎÎñ
ÔÚ·½·¨ÌύеÄÈÎÎñexecute(Runnable)½«ÔÚÖ´ÐгÌÐòÒѹرÕÁ˾ܾø ²¢ÇÒÒ²µ±Ö´ÐÐÆ÷ʹÓÃÓÐÏ޵ı߽çÁ½¸ö×î´óÏ̺߳͹¤×÷¶ÓÁÐÈÝÁ¿ ÇÒ±¥ºÍ¡£ ÔÚÈÎÒ»Çé¿öÏ execute·½·¨µ÷ÓÃRejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor)ÆäµÄ·½·¨RejectedExecutionHandler ¡£ ÌṩÁËËĸöÔ¤¶¨ÒåµÄ´¦Àí³ÌÐò²ßÂÔ
ÔÚĬÈϵÄThreadPoolExecutor.AbortPolicy ´¦Àí³ÌÐòÔھܾøʱ»áÅ׳öÔËÐÐʱRejectedExecutionException ¡£
ÔÚThreadPoolExecutor.CallerRunsPolicy µ÷ÓÃexecute×Ô¼ºµÄÏß³ÌÔËÐÐÈÎÎñ¡£ ÕâÌṩÁËÒ»ÖÖ¼òµ¥µÄ·´À¡¿ØÖÆ»úÖÆ ¸Ã»úÖƽ«¼õÂýÐÂÈÎÎñµÄÌá½»Ëٶȡ£
ÔÚThreadPoolExecutor.DiscardPolicy ¼òµ¥µØɾ³ýÁËÎÞ·¨Ö´ÐеÄÈÎÎñ¡£
ÔÚThreadPoolExecutor.DiscardOldestPolicy Èç¹ûδ¹Ø±ÕÖ´ÐгÌÐò Ôò½«¶ªÆú¹¤×÷¶ÓÁпªÍ·µÄÈÎÎñ È»ºóÖØÊÔÖ´ÐÐ ¸Ã²Ù×÷¿ÉÄÜÔÙ´Îʧ°Ü µ¼ÖÂÖظ´Ö´Ðд˲Ù×÷ ¡£
¿ÉÒÔ¶¨ÒåºÍʹÓÃÆäËûÖÖÀàµÄRejectedExecutionHandlerÀà¡£ ÕâÑù×öÐèÒª¸ñÍâСÐÄ ÓÈÆäÊÇÔÚÉè¼Æ²ßÂÔ½öÔÚÌض¨ÈÝÁ¿»òÅŶӲßÂÔϲÅÄܹ¤×÷ʱ¡£
¹Ò¹³·½·¨
´ËÀàÌṩprotected¿ÉÖØдµÄ**beforeExecute**(Thread, Runnable)ºÍafterExecute(Runnable, Throwable)·½·¨ ÕâЩ·½·¨ÔÚÿ¸öÈÎÎñÖ´ÐÐÇ°ºó±»µ÷ÓᣠÕâЩ¿ÉÒÔÓÃÀ´²Ù×ÝÖ´Ðл·¾³¡£ ÀýÈç ÖØгõʼ»¯ThreadLocals ÊÕ¼¯Í³¼ÆÐÅÏ¢»òÌí¼ÓÈÕÖ¾ÌõÄ¿¡£ ÁíÍâ Ò»µ©Ö´ÐгÌÐòÍêÈ«ÖÕÖ¹ ¿ÉÒÔterminated·½·¨terminatedÒÔÖ´ÐÐÐèÒªÖ´ÐеÄÈκÎÌØÊâ´¦Àí¡£
Èç¹û¹³×Ó»ò»Øµ÷·½·¨Òý·¢Òì³£ ÄÚ²¿¹¤×÷Ï߳̿ÉÄܽø¶øʧ°Ü²¢Í»È»ÖÕÖ¹¡£
¶ÓÁÐά»¤
·½·¨getQueue()ÔÊÐí·ÃÎʹ¤×÷¶ÓÁÐ ÒÔ½øÐÐ**¼àÊӺ͵÷ÊÔ**¡£ Ç¿ÁÒ½¨Òé²»Òª½«´Ë·½·¨ÓÃÓÚÈκÎÆäËûÄ¿µÄ¡£ µ±È¡Ïû´óÁ¿ÅŶӵÄÈÎÎñʱ ¿ÉÒÔʹÓÃÌṩµÄÁ½ÖÖ·½·¨remove(Runnable)ºÍpurgeÀ´°ïÖú»ØÊÕ´æ´¢¡£
¶¨°¸
ÕâÔÚ³ÌÐò²»ÔÙ±»ÒýÓà ҲûÓÐÊ£ÓàµÄÏ߳̽«³ÉΪ³Øshutdown×Ô¶¯¡£ Èç¹û¼´Ê¹ÔÚÓû§Íü¼Çµ÷ÓÃshutdownҲҪȷ±£»ØÊÕδÒýÓÃµÄ³Ø Ôò±ØÐëͨ¹ýʹÓÃÁãºËÐÄÏ̵߳ÄÏÂÏÞºÍ/»òÉèÖÃallowCoreThreadTimeOut(boolean)À´ÉèÖÃÊʵ±µÄ±£»îʱ¼ä ÒÔ°²ÅÅδʹÓõÄÏß³Ì×îÖÕËÀµôallowCoreThreadTimeOut(boolean) ¡£
À©Õ¹Ê¾Àý¡£ ´ËÀàµÄ´ó¶àÊýÀ©Õ¹¶¼¸²¸ÇÒ»¸ö»ò¶à¸öÊܱ£»¤µÄhook·½·¨¡£ ÀýÈç ÒÔÏÂÊÇÒ»¸ö×ÓÀà ËüÌí¼ÓÁËÒ»¸ö¼òµ¥µÄÔÝÍ£/¼ÌÐø¹¦ÄÜ
java
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock new ReentrantLock();
private Condition unpaused pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eaf82186fc2b4e63aa13ff99321f0256~tplv-k3u1fbpfcp-zoom-1.image)
## ÏëÒªÁ˽â͸³¹Ïß³Ì³Ø ÏÈÁ˽âÒ»ÏÂḬ̈߳É
ÒÔÏ»ùÓÚJDK1.8½éÉÜ
Õª×ÔÔ´ÂëƬ¶Ì һЩºËÐĵĶ¨Òå
java
private volatile String name; // Ï̵߳ÄÃû×Ö
// Ï̵߳ÄÓÅÏȼ¶ ĬÈÏΪ5 ¿É×ÔÐÐÉèÖà Խ´ó´ú±í¿ÉÒÔ»ñµÃµÄʱ¼äƬ¼¸ÂÊÔ½¸ß
private int priority;
/* ÊÇ·ñÊÇÊØ»¤Ïß³Ì ÊØ»¤Ïß³ÌÔÚJVM½áÊøʱ×Ô¶¯Ïú»Ù */
private boolean daemon false;
/* ½«ÒªÔËÐеÄÄ¿±ê. */
private Runnable target;
/* Ïß³Ì×é-¾ÍÊǸøÏ̷߳Ö×é ͦ¼òµ¥,³õʼ»¯»á±»·ÖÅä ÓëÏ̳߳ØÎÞÖ±½ÓÁªÏµ */
private ThreadGroup group;
/* ´ËÏ̵߳ÄÉÏÏÂÎÄClassLoader */
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
private AccessControlContext inheritedAccessControlContext;
/* ÓÃÓÚÃüÃûÊÇÄĸöÏ̵߳ıàºÅ */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber
}
/* Óë´ËÏß³ÌÓйصÄThreadLocalÖµ¡£¸ÃÓ³ÉäÓÉThreadLocalÀàά»¤ */
ThreadLocal.ThreadLocalMap threadLocals null;
/*
*Óë´ËÏß³ÌÓйصÄInheritableThreadLocalÖµ¡£¸ÃÓ³ÉäÓÉInheritreadLableThocalÀàά»¤.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals null;
/*
´ËÏß³ÌÇëÇóµÄ¶ÑÕ»´óС Èç¹û´´½¨Õßδָ¶¨¶ÑÕ»´óС ÔòΪ0¡£
VM¿ÉÒÔ¸ù¾Ý´ËÊý×ÖÖ´ÐÐ*ϲ»¶µÄÈκÎÊÂÇé һЩÐéÄâ»ú½«ºöÂÔËü.
*/
private long stackSize;
/*
* Thread ID
*/
private long tid;
/* ÓÃÓÚÉú³ÉÏß³ÌID */
private static long threadSeqNumber;
/* Java thread status
*/
private volatile int threadStatus
×¢Ò⼸¸öÖØÒªµÄ·½·¨
1.ÓÐÒ»¸ö**start**·½·¨ Õâ¸ö·½·¨ÀïÃæµ÷ÓÃÁ˲Ù×÷ϵͳ ÀûÓòÙ×÷ϵͳȥµ÷ÓÃÎÒÃǵÄrun·½·¨¡£
java
private native void start0();
\2. **interruput**·½·¨ ÕâÖ»ÊÇÒ»¸ö±êÖ¾ ²»»áÁ¢¼´ÖжÏ
interrupted()ÊǾ²Ì¬·½·¨ ÄÚ²¿ÊµÏÖÊǵ÷Óõĵ±Ç°Ï̵߳ÄisInterrupted() ²¢ÇÒ**»áÖØÖõ±Ç°Ï̵߳ÄÖжÏ״̬**
isInterrupted()ÊÇʵÀý·½·¨ Êǵ÷Óø÷½·¨µÄ¶ÔÏóËù±íʾµÄÄǸöÏ̵߳ÄisInterrupted() **²»»áÖØÖõ±Ç°Ï̵߳ÄÖжÏ״̬**
\3. **join** ÃæÊÔ³£ÎÊ ÆäʵÊÇͨ¹ý**waitÀ´×èÈû**Ïß³Ì ÀýÈç t1.join() ÎÞÏÞÖÆ×èÈût1Íê³É ÔÚ¼ÌÐøÖ´ÐÐÏÂÃæµÄ·½·¨¡£
\4. getAllStackTraces »ñÈ¡ËùÓÐÏ̵߳ĶÑÕ»ÐÅÏ¢ ¿ÉÒÔÓÃÀ´À©Õ¹¼à¿Ø¡£
ÆäËû·½·¨´ó¼Ò¿´¿´¾ÍÐС£
ÏÂÃæ½²½²Ï̵߳Ä״̬
java
/**
ÉÐδÆô¶¯µÄÏ̵߳ÄÏß³Ì״̬
*/
NEW,
/**
¿ÉÔËÐÐÏ̵߳ÄÏß³Ì״̬¡£×´Ì¬Îª¿ÉÔËÐеÄÏß³ÌÕýÔÚJavaÐéÄâ»úÖÐÖ´ÐÐ
µ«ÊÇ¿ÉÄÜÕýÔڵȴýÀ´×Ô²Ù×÷ϵͳµÄÆäËû×ÊÔ´ ÀýÈç´¦ÀíÆ÷¡£
*/
RUNNABLE,
/**
Ï̵߳ÄÏß³Ì״̬±»×èÈû µÈ´ý¼àÊÓÆ÷Ëø¶¨¡£´¦ÓÚ×èÈû״̬µÄÏß³ÌÕýÔڵȴý¼àÊÓ
Æ÷Ëø¶¨ÊäÈëͬ²½¿é/·½·¨»òµ÷ÓÃObject.waitºóÖØÐÂÊäÈëͬ²½¿é/·½·¨¡£
Çø±ð¾ÍÊÇÓиöwhile
*/
// synchronized(this)
// {
// while (flag)
// {
// obj.wait();
// }
// }
BLOCKED,
/**
*µÈ´ýÏ̵߳ÄÏß³Ì״̬¡£ÓÉÓÚµ÷ÓÃÒÔÏÂÆäÖÐÒ»ÖÖ·½·¨ Ï̴߳¦Óڵȴý״̬
Object.waitÎÞ³¬Ê±
Thread.joinûÓг¬Ê±
LockSupport.park µÈ´ý״̬
ÕýÔڵȴýÁíÒ»¸öÏß³ÌÖ´ÐÐÌض¨²Ù×÷¡£ÀýÈç ÔÚij¸ö¶ÔÏóÉϵ÷ÓÃ
Object.wait µÄÏß³ÌÕýÔڵȴýÁíÒ»¸öÏ̵߳÷Óà Object.notify
»ò¸Ã¶ÔÏóÉϵÄObject.notifyAll ÃûΪ Thread.joinµÄÏß³ÌÕýÔڵȴýÖ¸¶¨
µÄÏß³ÌÖÕÖ¹¡£
*/
WAITING,
/**
¾ßÓÐÖ¸¶¨µÈ´ýʱ¼äµÄµÈ´ýÏ̵߳ÄÏß³Ì״̬¡£Ïß³ÌÓÉÓÚÒÔÖ¸¶¨µÄÕýµÈ´ýʱ¼äµ÷ÓÃÒÔÏÂ
·½·¨Ö®Ò»¶ø´¦ÓÚ¶¨Ê±µÈ´ý״̬
Thread.sleep,
Object.wait long
Thread.join(long)
LockSupport.parkNanos
LockSupport.parkUntil
*/
TIMED_WAITING,
/**
ÖÕÖ¹Ï̵߳ÄÏß³Ì״̬¡£*Ïß³ÌÒÑÍê³ÉÖ´ÐÐ
*/
TERMINATED;
Ïß³ÌÁ˽â²î²»¶àÁË ½ÓÏÂÀ´¿´¿´Ï̳߳ذÉ
Ï̳߳ØThreadPoolExecutor
¿´¿´Ï̳߳صÄUMLͼ°É
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3046933208cf4aaeb7c37edc1f945247~tplv-k3u1fbpfcp-zoom-1.image)
ÎÒÃÇ´ÓÉÏÍùÏÂÒÀ´Î·ÖÎö
java
/ **
*ÔÚ½«À´µÄij¸öʱ¼äÖ´Ðиø¶¨ÃüÁî¡£ÓÉ ExecutorʵÏÖ¾ö¶¨ ÃüÁî¿ÉÒÔÔÚÐÂÏß³Ì
³Ø»òµ÷ÓÃÏß³ÌÖÐÖ´ÐС£ paramÃüÁî¿ÉÔËÐÐÈÎÎñ Èç¹ûÎÞ·¨½ÓÊÜ´ËÈÎÎñ
Ôò throws RejectedExecutionException
Èç¹ûÃüÁîΪnull Ôò throws NullPointerException
*
/
void execute(Runnable command);
¼òµ¥À´Ëµ¾ÍÊǵ÷¶ÈÏß³ÌÀ´Ö´ÐÐÈÎÎñ Óû§Ö»Ðè**ÌṩRunnable¶ÔÏó** ½«ÈÎÎñµÄÔËÐÐ**Âß¼Ìá½»µ½Ö´ÐÐÆ÷****(**Executor)ÖÐ
**ExecutorService**½Ó¿ÚÔö¼ÓÁËһЩÄÜÁ¦ 1 À©³äÖ´ÐÐÈÎÎñµÄÄÜÁ¦ ²¹³ä¿ÉÒÔΪһ¸ö»òÒ»Åú**Òì²½ÈÎÎñÉú³ÉFuture**µÄ·½·¨ 2 ÌṩÁË**¹Ü¿ØÏ̳߳Ø**µÄ·½·¨ ±ÈÈçÍ£Ö¹Ï̳߳صÄÔËÐС£¿ÉÒÔ´ÓÉÏÃæUMLͼ¼òµ¥¿´³ö¡£
java
public interface ExecutorService extends Executor {
// ÇëÇó¹Ø±Õ¡¢·¢Éú³¬Ê±»òÕßµ±Ç°Ïß³ÌÖÐ¶Ï ÎÞÂÛÄÄÒ»¸öÊ×ÏÈ·¢ÉúÖ®ºó ¶¼½«µ¼ÖÂ×èÈû Ö±µ½ËùÓÐÈÎÎñÍê³ÉÖ´ÐС£
boolean awaitTermination(long timeout, TimeUnit unit);
// Ö´Ðиø¶¨µÄÈÎÎñ µ±ËùÓÐÈÎÎñÍê³Éʱ ·µ»Ø±£³ÖÈÎÎñ״̬ºÍ½á¹ûµÄ Future ÁÐ±í¡£
T List Future T invokeAll(Collection ? extends Callable T tasks);
// Ö´Ðиø¶¨µÄÈÎÎñ µ±ËùÓÐÈÎÎñÍê³É»ò³¬Ê±ÆÚÂúʱ ÎÞÂÛÄĸöÊ×ÏÈ·¢Éú ·µ»Ø±£³ÖÈÎÎñ״̬ºÍ½á¹ûµÄ Future ÁÐ±í¡£
T List Future T invokeAll(Collection ? extends Callable T tasks, long timeout, TimeUnit unit);
// Ö´Ðиø¶¨µÄÈÎÎñ Èç¹ûij¸öÈÎÎñÒѳɹ¦Íê³É Ò²¾ÍÊÇδÅ׳öÒì³£ Ôò·µ»ØÆä½á¹û¡£
T T invokeAny(Collection ? extends Callable T tasks);
// Ö´Ðиø¶¨µÄÈÎÎñ Èç¹ûÔÚ¸ø¶¨µÄ³¬Ê±ÆÚÂúǰij¸öÈÎÎñÒѳɹ¦Íê³É Ò²¾ÍÊÇδÅ׳öÒì³£ Ôò·µ»ØÆä½á¹û¡£
T T invokeAny(Collection ? extends Callable T tasks, long timeout, TimeUnit unit);
// Èç¹û´ËÖ´ÐгÌÐòÒÑ¹Ø±Õ Ôò·µ»Ø true¡£
boolean isShutdown();
// Èç¹û¹Ø±ÕºóËùÓÐÈÎÎñ¶¼ÒÑÍê³É Ôò·µ»Ø true¡£
boolean isTerminated();
// Æô¶¯Ò»´Î˳Ðò¹Ø±Õ Ö´ÐÐÒÔÇ°Ìá½»µÄÈÎÎñ µ«²»½ÓÊÜÐÂÈÎÎñ¡£
void shutdown();
// ÊÔͼֹͣËùÓÐÕýÔÚÖ´ÐеĻÈÎÎñ ÔÝÍ£´¦ÀíÕýÔڵȴýµÄÈÎÎñ ²¢·µ»ØµÈ´ýÖ´ÐеÄÈÎÎñÁÐ±í¡£
List Runnable shutdownNow();
// Ìá½»Ò»¸ö·µ»ØÖµµÄÈÎÎñÓÃÓÚÖ´ÐÐ ·µ»ØÒ»¸ö±íʾÈÎÎñµÄδ¾ö½á¹ûµÄ Future¡£
T Future T submit(Callable T task);
// Ìá½»Ò»¸ö Runnable ÈÎÎñÓÃÓÚÖ´ÐÐ ²¢·µ»ØÒ»¸ö±íʾ¸ÃÈÎÎñµÄ Future¡£
Future ? submit(Runnable task);
// Ìá½»Ò»¸ö Runnable ÈÎÎñÓÃÓÚÖ´ÐÐ ²¢·µ»ØÒ»¸ö±íʾ¸ÃÈÎÎñµÄ Future¡£
T Future T submit(Runnable task, T result);
}
**AbstractExecutorService**ÔòÊÇÉϲãµÄ³éÏóÀà ÕâÀïÑÓÉì³ö**Future** ¼òµ¥µÄ˵¾ÍÊÇ»ñÈ¡Òì²½Ö´ÐеĽá¹û ÀýÈçÔÚNettyÖÐ ÎÒÃÇ´¦ÀíÏûÏ¢ÊÇͨ¹ýÒ»¸öË«ÏòÁ´±íÀ´´¦ÀíµÄ ÐèÒª¶ÔÏûÏ¢Ò»²ã²ã´¦Àí ËùÒÔ˵ÕâÀïÒ²Óõ½ÁËFutureÀ´»ñÈ¡ÏûÏ¢´¦ÀíµÄ½á¹û¡£
×îϲãµÄʵÏÖÀà**ThreadPoolExecutor**ʵÏÖ×ÔÓµÄÔËÐв¿·Ö ThreadPoolExecutor½«»áÒ»·½Ãæ**ά»¤×ÔÉíµÄÉúÃüÖÜÆÚ** ÁíÒ»·½Ãæͬʱ**¹ÜÀíÏ̺߳ÍÈÎÎñ** ʹÁ½ÕßÁ¼ºÃµÄ½áºÏ´Ó¶øÖ´Ðв¢ÐÐÈÎÎñ¡£
Ï̳߳ØÉúÃüÖÜÆÚ
**Ï̳߳صÄÉúÃüÖÜÆÚ**Ò²¾ÍÊÇÏ̳߳ØÔÚÔËÐÐʱËù¾ÀúµÄ**Ï̳߳Ø״̬**¡£Ï̳߳ØÄÚ²¿Ê¹ÓÃÒ»¸ö±äÁ¿Î¬»¤Á½¸öÖµ **ÔËÐÐ״̬**(runState)ºÍ**Ïß³ÌÊýÁ¿** (workerCount)¡£ÔÚ¾ßÌåʵÏÖÖÐ Ï̳߳ؽ«ÔËÐÐ״̬(runState)¡¢Ïß³ÌÊýÁ¿ (workerCount)Á½¸ö¹Ø¼ü²ÎÊýµÄά»¤**·ÅÔÚÁËÒ»Æð** ÈçÏ´úÂëËùʾ
java
private final AtomicInteger ctl new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS Integer.SIZE - 3; // 32 -3
private static final int CAPACITY (1 COUNT_BITS) - 1; // 1 29 - 1 2^29 -1
// runState is stored in the high-order bits
private static final int RUNNING -1 COUNT_BITS; // -2^29 ?11100000000000000000000000000000?
private static final int SHUTDOWN 0 COUNT_BITS; // 0 00000000000000000000000000000000?
private static final int STOP 1 COUNT_BITS; // 2^29 ?00100000000000000000000000000000?
private static final int TIDYING 2 COUNT_BITS; // 2*2^29 ?01000000000000000000000000000000?
private static final int TERMINATED 3 COUNT_BITS; // 3*2^29 ?01100000000000000000000000000000?
// Packing and unpacking ctl
private static int runStateOf(int c) { return c ~CAPACITY; } // Ï̳߳ØÔËÐÐ״̬
private static int workerCountOf(int c) { return c CAPACITY; } // Ïß³ÌÊýÁ¿
private static int ctlOf(int rs, int wc) { return rs | wc; }
ctlÕâ¸öAtomicIntegerÀàÐÍ ÊǶÔÏ̳߳صÄÔËÐÐ״̬ºÍÏ̳߳ØÖÐÓÐЧÏ̵߳ÄÊýÁ¿½øÐпØÖƵÄÒ»¸ö×ֶΠËüͬʱ°üº¬Á½²¿·ÖµÄÐÅÏ¢ Ï̳߳صÄÔËÐÐ״̬ (runState) ºÍÏ̳߳ØÄÚÓÐЧÏ̵߳ÄÊýÁ¿ (workerCount) **¸ß3λ±£´ærunState** **µÍ29λ±£´æworkerCount** Á½¸ö±äÁ¿Ö®¼ä»¥²»¸ÉÈÅ¡£ÓÃÒ»¸ö±äÁ¿È¥´æ´¢Á½¸öÖµ ¿É±ÜÃâÔÚ×öÏà¹Ø¾ö²ßʱ ³öÏÖ²»Ò»ÖµÄÇé¿ö **²»±ØΪÁËά»¤Á½ÕßµÄÒ»Ö ¶øÕ¼ÓÃËø×ÊÔ´**¡£Í¨¹ýÔĶÁÏ̳߳ØÔ´´úÂëÒ²¿ÉÒÔ·¢ÏÖ ¾³£³öÏÖҪͬʱÅжÏÏ̳߳ØÔËÐÐ״̬ºÍÏß³ÌÊýÁ¿µÄÇé¿ö¡£Ï̳߳ØÒ²ÌṩÁËÈô¸É·½·¨È¥¹©Óû§»ñµÃÏ̳߳ص±Ç°µÄÔËÐÐ״̬¡¢Ï̸߳öÊý¡£ÕâÀﶼʹÓõÄÊÇλÔËËãµÄ·½Ê½ Ïà±ÈÓÚ»ù±¾ÔËËã ËÙ¶ÈÒ²»á¿ìºÜ¶à¡£
ÈçÉÏ´úÂëÖиø³öÁËÏ̳߳Ø״̬µÄ¶þ½øÖÆÊý¾Ý ÏÂÃæ·Ö±ðÃèÊöÒ»ÏÂ
- **RUNNING**: ÄÜ**½ÓÊÜÐÂÌá½»µÄÈÎÎñ** ²¢ÇÒÒ²ÄÜ´¦Àí×èÈû¶ÓÁÐÖеÄÈÎÎñ¡£
- **SHUTDOWN**: ¹Ø±Õ״̬ **²»ÔÙ½ÓÊÜÐÂÌá½»µÄÈÎÎñ** µ«È´¿ÉÒÔ¼ÌÐø**´¦Àí×èÈû¶ÓÁÐÖÐÒѱ£´æµÄÈÎÎñ**¡£
- **STOP** : **²»ÄܽÓÊÜÐÂÈÎÎñ Ò²²»´¦Àí**¶ÓÁÐÖеÄÈÎÎñ »áÖжÏÕýÔÚ´¦ÀíÈÎÎñµÄÏ̡߳£
- **TIDYING** : ËùÓеÄÈÎÎñ¶¼ÒѾ**ÖÕÖ¹**ÁË workerCount ÓÐЧÏß³ÌÊý Ϊ0¡£
- **TERMINATED** : ÔÚ**terminated ·½·¨Ö´ÐÐÍê³Éºó**½øÈë¸Ã״̬¡£
Ï̳߳ØÔËÐÐÁ÷³Ì
±¾ÎĵĺËÐÄÖص㡣
Ê×ÏÈ ËùÓÐÈÎÎñµÄµ÷¶È¶¼ÊÇÓÉ**execute**·½·¨Íê³ÉµÄ Õⲿ·ÖÍê³ÉµÄ¹¤×÷ÊÇ ¼ì²éÏÖÔÚ**Ï̳߳صÄÔËÐÐ״̬¡¢ÔËÐÐÏß³ÌÊý¡¢ÔËÐвßÂÔ** ¾ö¶¨½ÓÏÂÀ´Ö´ÐеÄÁ÷³Ì ÊÇ**Ö±½ÓÉêÇëÏß³ÌÖ´ÐÐ** »òÊÇ**»º³åµ½¶ÓÁÐÖÐÖ´ÐÐ** Òà»òÊÇ**Ö±½Ó¾Ü¾ø¸ÃÈÎÎñ**
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a7edb97ea88e40b19b758f475fa4c70b~tplv-k3u1fbpfcp-zoom-1.image)
ÎÒÃÇÖ±½Ó¿´Ò»ÏÂÔ´Âë ÕâÑù±È½ÏÖ±¹Û Ó¡Ïó±È½ÏÉî¿Ì ´úÂë²»ÄÑ¡£
java
public void execute(Runnable command) {
if (command null)
throw new NullPointerException();
int c ctl.get();
if (workerCountOf(c) corePoolSize) { // Èç¹ûСÓÚºËÐÄÏß³ÌÊý
if (addWorker(command, true))
return;
c ctl.get();
}
// offer¾ÍÊÇÈç¹û¶ÓÁÐδÂú¾ÍÌí¼Óµ½¶ÓÁÐ
if (isRunning(c) workQueue.offer(command)) {
int recheck ctl.get();
if (! isRunning(recheck) remove(command))
reject(command);
else if (workerCountOf(recheck) 0)
addWorker(null, false);
}
// Èç¹û¶ÓÁÐÒ²ÂúÁË ¾ÍÖ±½ÓÆðÒ»¸öÏß³Ì Ê§°Ü×߾ܾø²ßÂÔ
else if (!addWorker(command, false))
reject(command);
}
java
ÏÂÃæÎÒÃÇÀ´¿´¿´addworkÏà¹Ø²¿·Ö´úÂëÈ¥µôÁ˲¿·ÖÌõ¼þÅжÏ
java
private boolean addWorker(Runnable firstTask, boolean core) {
if (compareAndIncrementWorkerCount(c))
break retry; // Ôö¼ÓÏß³ÌÊý Ìø³öÑ»·
try {
w new Worker(firstTask); //this.thread getThreadFactory().newThread(this);
final Thread t w.thread; // ÕâÀïͨ¹ýÏ̹߳¤³§newÒ»¸öÏß³Ì
if (t ! null) {
final ReentrantLock mainLock this.mainLock;
mainLock.lock(); // ¶ÀÕ¼Ëø-
try {
int rs runStateOf(ctl.get());// »ñÈ¡Ï̳߳Ø״̬
if (rs SHUTDOWN || // Ï̳߳ØÔÚÔËÐлòÕßshutdown
(rs SHUTDOWN firstTask null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);// Ìí¼ÓÈÎÎñµ½×èÈû¶ÓÁÐ
int s workers.size();
if (s largestPoolSize)
largestPoolSize
workerAdded true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start(); // Æô¶¯Ïß³Ì
workerStarted true;
}
}
return workerStarted;
ÉÏÃæ¿ÉÒÔ¿´µ½t.start()¿ªÆôÁËϵͳÏ̵߳÷¶È ½ÓÏÂÀ´ÔÚ¸úÏÂrun·½·¨
java
public void run() {
runWorker(this);
}
¿ÉÒÔ¿´µ½ ½ÓÏÂÀ´Ö´ÐÐÁËrunworker this ,this¾ÍÊǸոռÓÈëµÄwÈÎÎñ¡£
java
final void runWorker(Worker w) {
Thread wt Thread.currentThread();
Runnable task w.firstTask;
w.firstTask null;
w.unlock(); // ÒÔ¶ÀÕ¼µÄ·½Ê½ÊÍ·Å×ÊÔ´
boolean completedAbruptly true;
try {
// Èç¹ûtask null ¾ÍgetTask»ñÈ¡Ò»¸öÈÎÎñ
while (task ! null || (task getTask()) ! null) {
w.lock(); // 1.ÒÔ¶ÀÕ¼¶î·½Ê½»ñµÃ×ÊÔ´ ºöÂÔÒì³£
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted()
runStateAtLeast(ctl.get(), STOP)))
!wt.isInterrupted())
wt.interrupt();
try {
// 2.¿ÉÀ©Õ¹ ÓÃÓÚÖØгõʼ»¯ threadlocals »òÕßÖ´ÐÐÈÕÖ¾¼Ç¼¡£
beforeExecute(wt, task);
Throwable thrown null;
try {
task.run();// ÈÎÎñÖ´ÐÐ
} catch (RuntimeException x) {
thrown throw x;
} catch (Error x) {
thrown throw x;
} catch (Throwable x) {
thrown throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task null;
w.completedTasks
w.unlock();
}
}
completedAbruptly false;
} finally {
// Ï̻߳ØÊÕ
processWorkerExit(w, completedAbruptly);
}
}
·ÖÎöÒ»ÏÂgetTask
java
boolean timed allowCoreThreadTimeOut || wc corePoolSize;
Runnable r timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
¼òµ¥µÄ˵Èç¹ûÉèÖÃÁ˺ËÐÄÏ߳̿ÉÒÔ³¬Ê± true»òÕßµ±Ç°Ïß³ÌÊý ºËÐÄÏß³ÌÊý ¾ÍÏÞʱ»ñÈ¡ÈÎÎñ ·ñÔò¾Í×èÈû»ñÈ¡ÈÎÎñ¡£
Âß¼Æäʵ¶¼ºÜ¼òµ¥ ÓÐЩ¶«Î÷»¹ÊÇÐèÒªÎÒÃÇ×Ðϸ·ÖÎöһϠÀýÈç´úÂëÖÐ
µÚÒ»µã
java
1.w.lock()
2.public void lock() { acquire(1); }
3.public final void acquire(int arg) { // class AbstractQueuedSynchronizer
if (!tryAcquire(arg)
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
¿ÉÒÔ¿´µ½ÕâÀïÊÇÖ±½Óµ÷ÓõÄ**AQSµÄ¶ÀÕ¼Ëø-¹«Æ½Ëø**ʵÏÖ·½Ê½ ¶øÔÚÏ̻߳ØÊÕprocessWorkerExit Õâ¸ö·½·¨Ê¹ÓõÄÊÇ**AQSµÄ¶ÀÕ¼Ëø-·Ç¹«Æ½Ëø**
java
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn t adjusted
decrementWorkerCount();
// ĬÈÏʹÓ÷ǹ«Æ½Ëø new NonfairSync()
final ReentrantLock mainLock this.mainLock;
mainLock.lock();
try {
// ËøÄÚʵÏÖÒƳýÈÎÎñ ͬʱҲÒƳýÁËThreadÒýÓÃ
completedTaskCount w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
// ³¢ÊÔÖжÏÏß³Ì Èç¹ûÏ̳߳ØÕýÔÚ¹Ø±Õ Ôò¹Ø±ÕÏ̳߳Ø
tryTerminate();
int c ctl.get();
if (runStateLessThan(c, STOP)) { // Èç¹ûÏ̳߳ØûÓÐÍ£Ö¹
if (!completedAbruptly) { // ûÓÐÒì³£½áÊø
// Ï̳߳Ø×îС¿ÕÏÐÊý ÔÊÐícore thread³¬Ê±¾ÍÊÇ0 ·ñÔò¾ÍÊÇcorePoolSize
int min allowCoreThreadTimeOut ? 0 : corePoolSize;
// Èç¹ûmin 0µ«ÊǶÓÁв»Îª¿ÕÒª±£Ö¤ÓÐ1¸öÏß³ÌÀ´Ö´ÐжÓÁÐÖеÄÈÎÎñ
if (min 0 ! workQueue.isEmpty())
min
// // Ïß³ÌÊý²»Îª¿Õ
if (workerCountOf(c) min)
return; // replacement not needed
}
// 1.Ïß³ÌÒì³£Í˳ö
// 2.Ï̳߳ØΪ¿Õ µ«ÊǶÓÁÐÖл¹ÓÐÈÎÎñûִÐÐ ¿´addWoker·½·¨¶ÔÕâÖÖÇé¿öµÄ´¦Àí
addWorker(null, false);
}
}
¼òµ¥·ÖÎöÒ»ÏÂÏ̻߳ØÊÕÁ÷³Ì:
1. lock·½·¨Ò»µ©**»ñÈ¡Á˶ÀÕ¼Ëø** ±íʾµ±Ç°Ïß³Ì**ÕýÔÚÖ´ÐÐÈÎÎñ**ÖС£
2. Èç¹ûÕýÔÚÖ´ÐÐÈÎÎñ Ôò**²»Ó¦¸ÃÖжÏÏß³Ì**¡£
3. Èç¹û¸ÃÏß³ÌÏÖÔÚ**²»ÊǶÀÕ¼ËøµÄ**״̬ Ò²¾ÍÊÇ**¿ÕÏеÄ״̬** ˵Ã÷ËüûÓÐÔÚ´¦ÀíÈÎÎñ Õâʱ**¿ÉÒÔ¶Ô¸ÃÏ߳̽øÐÐÖжÏ**¡£
4. Ï̳߳ØÔÚÖ´ÐÐ**shutdown**·½·¨»ò**tryTerminate**·½·¨Ê±»áµ÷ÓÃ**interruptIdleWorkers**·½·¨À´**ÖжϿÕÏеÄÏß³Ì** interruptIdleWorkers·½·¨»áʹÓÃ**tryLock**·½·¨À´ÅжÏ**Ï̳߳Ø**ÖеÄ**Ïß³ÌÊÇ·ñÊÇ¿ÕÏÐ״̬** Èç¹ûÏß³ÌÊÇ¿ÕÏÐ״̬Ôò**¿ÉÒÔ°²È«»ØÊÕ**¡£
java
final void tryTerminate() {
for (;;) {
int c ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) SHUTDOWN ! workQueue.isEmpty()))
return;
// ÕâÀï¿ÉÒÔ¿´µ½Ö»ÒªÏß³ÌÊý 0 Ï߳̾ͿÉÒÔ±»»ØÊÕ
if (workerCountOf(c) ! 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
java
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t w.thread;
// ÕâÀï¿´µ½½øÐÐÁËtrylockÅжÏ
if (!t.isInterrupted() w.tryLock()) {
try {
// ½øÐÐÏß³ÌÖжϱêʶ
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
ÀýÈç AÏß³Ìlock()ʱ »áµ÷ÓÃ**tryAcquire()¶ÀÕ¼¸ÃËø²¢½«state 1**¡£´Ëºó ÆäËûÏß³ÌÔÙtryAcquire()ʱ¾Í»áʧ°Ü Ö±µ½AÏß³Ì**unlock()µ½state 0** ¼´ÊÍ·ÅËø Ϊֹ ÆäËüÏ̲߳ÅÓлú»á»ñÈ¡¸ÃËø¡£µ±È» ÊÍ·ÅËø֮ǰ AÏß³Ì×Ô¼ºÊÇ¿ÉÒÔÖظ´»ñÈ¡´ËËøµÄ state»áÀÛ¼Ó Õâ¾ÍÊÇ¿ÉÖØÈëµÄ¸ÅÄî¡£µ«Òª×¢Òâ »ñÈ¡¶àÉٴξÍÒªÊͷŶàô´Î ÕâÑù²ÅÄܱ£Ö¤stateÊÇÄܻص½Áã̬µÄ¡£
ÔÙÒÔ**CountDownLatch**ÒÔÀý ÈÎÎñ·ÖΪN¸ö×ÓÏß³ÌÈ¥Ö´ÐÐ stateÒ²³õʼ»¯ÎªN ×¢ÒâNÒªÓëÏ̸߳öÊýÒ»Ö ¡£ÕâN¸ö×ÓÏß³ÌÊDz¢ÐÐÖ´ÐÐµÄ Ã¿¸ö×ÓÏß³ÌÖ´ÐÐÍêºócountDown()Ò»´Î state»áCAS¼õ1¡£µÈµ½**ËùÓÐ×ÓÏ̶߳¼Ö´ÐÐÍêºó(¼´state 0)** »á**unpark()**Ö÷µ÷ÓÃÏß³Ì È»ºóÖ÷µ÷ÓÃÏ߳̾ͻá´Óawait()º¯Êý·µ»Ø ¼ÌÐøºóÓද×÷¡£
Ò»°ãÀ´Ëµ ×Ô¶¨Òåͬ²½Æ÷ҪôÊǶÀÕ¼·½·¨ ҪôÊǹ²Ïí·½Ê½ ËûÃÇÒ²Ö»ÐèʵÏÖtryAcquire-tryRelease¡¢tryAcquireShared-tryReleaseSharedÖеÄÒ»ÖÖ¼´¿É¡£µ«AQSÒ²Ö§³Ö×Ô¶¨Òåͬ²½Æ÷ͬʱʵÏÖ¶ÀÕ¼ºÍ¹²ÏíÁ½ÖÖ·½Ê½ ÈçReentrantReadWriteLock¡£
**ÈÎÎñ¾Ü¾ø**
Ï̳߳ØÖеÄ**Ïß³ÌÊýÄ¿´ïµ½maximumPoolSize**ʱ ¾ÍÐèÒª¾Ü¾øµô¸ÃÈÎÎñ ²ÉÈ¡ÈÎÎñ¾Ü¾ø²ßÂÔ ±£»¤Ï̳߳ء£
¾Ü¾ø²ßÂÔÊÇÒ»¸ö¹«¹²½Ó¿Ú ˵Ã÷ÎÒÃÇ¿ÉÒÔ×Ô¶¨ÒåÀ©Õ¹ ÆäÉè¼ÆÈçÏÂ
java
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
ÎÒÃÇ¿´¿´JDKÌṩµÄ¼¸Ö־ܾø²ßÂÔ
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24a97ae5f0d8410ba5f50b89aef667de~tplv-k3u1fbpfcp-zoom-1.image)
Ò»°ãÒµÎñÏ̲߳ÉÓà µ÷ÓÃÌá½»ÈÎÎñµÄÏß³ÌÈ¥´¦Àí Ç°ÌáÊÇËùÓÐÈÎÎñ¶¼Ö´ÐÐÍê±Ï
**ThreadPoolExecutor.CallerRunsPolicy**
java
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a { code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }
/**
µ÷ÓÃÕßÏß³ÌÖÐÖ´ÐÐÈÎÎñr
* param r the runnable task requested to be executed
* param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
ÒµÎñʵս
**³¡¾°1 ¿ìËÙÏìÓ¦Óû§ÇëÇó B/S**
´ÓÓû§ÌåÑé½Ç¶È¿´ Õâ¸ö½á¹ûÏìÓ¦µÄÔ½¿ìÔ½ºÃ Èç¹ûÒ»¸öÒ³Ãæ°ëÌ춼ˢ²»³ö Óû§¿ÉÄܾͷÅÆú²é¿´Õâ¸öÉÌÆ·ÁË¡£¶øÃæÏòÓû§µÄ¹¦ÄܾۺÏͨ³£·Ç³£¸´ÔÓ °éËæ×ŵ÷ÓÃÓëµ÷ÓÃÖ®¼äµÄ¼¶Áª¡¢**¶à¼¶¼¶Áª**µÈÇé¿ö ÒµÎñ¿ª·¢Í¬Ñ§ÍùÍù»áÑ¡ÔñʹÓÃÏ̳߳ØÕâÖÖ¼òµ¥µÄ·½Ê½ ½«**µ÷Ó÷â×°³ÉÈÎÎñ²¢ÐеÄÖ´ÐÐ** **Ëõ¶Ì**×ÜÌå**ÏìӦʱ¼ä**¡£ÁíÍâ ʹÓÃÏ̳߳ØÒ²ÊÇÓп¼Á¿µÄ ÕâÖÖ³¡¾°×îÖØÒªµÄ¾ÍÊÇ»ñÈ¡×î´óµÄÏìÓ¦ËÙ¶ÈÈ¥Âú×ãÓû§ ËùÒÔÓ¦¸Ã²»ÉèÖöÓÁÐÈ¥»º³å²¢·¢ÈÎÎñ **µ÷¸ß****corePoolSize**ºÍ**maxPoolSize**È¥¾¡¿ÉÄÜ**´´Ôì¶àµÄÏ߳̿ìËÙÖ´ÐÐÈÎÎñ**¡£
**³¡¾°2 ¿ìËÙ´¦ÀíÅúÁ¿ÈÎÎñ**
ÀëÏߵĴóÁ¿¼ÆËãÈÎÎñ ÐèÒª¿ìËÙÖ´ÐС£±ÈÈç˵ **ͳ¼Æij¸ö±¨±í** ÐèÒª¼ÆËã³öÈ«¹ú¸÷¸öÃŵêÖÐÓÐÄÄЩÉÌÆ·ÓÐijÖÖÊôÐÔ ÓÃÓÚºóÐøÓªÏú²ßÂԵķÖÎö ÄÇôÎÒÃÇÐèÒª²éѯȫ¹úËùÓÐÃŵêÖеÄËùÓÐÉÌÆ· ²¢ÇҼǼ¾ßÓÐijÊôÐÔµÄÉÌÆ· È»ºó¿ìËÙÉú³É±¨±í
ÕâÖÖ³¡¾°**ÐèÒªÖ´ÐдóÁ¿µÄÈÎÎñ** ÎÒÃÇÒ²»áÏ£ÍûÈÎÎñÖ´ÐеÄÔ½¿ìÔ½ºÃ¡£ÕâÖÖÇé¿öÏ ҲӦ¸ÃʹÓöàÏ̲߳ßÂÔ **²¢ÐмÆËã**¡£µ«ÓëÏìÓ¦ËÙ¶ÈÓÅÏȵij¡¾°Çø±ðÔÚÓÚ ÕâÀೡ¾°ÈÎÎñÁ¿¾Þ´ó ²¢²»ÐèҪ˲ʱµÄÍê³É ¶øÊǹØ×¢ÈçºÎʹÓÃÓÐÏÞµÄ×ÊÔ´ ¾¡¿ÉÄÜÔÚµ¥Î»Ê±¼äÄÚ´¦Àí¸ü¶àµÄÈÎÎñ Ò²¾ÍÊÇ**ÍÌÍÂÁ¿ÓÅÏÈ**µÄÎÊÌâ¡£ËùÒÔÓ¦¸Ã**ÉèÖöÓÁÐÈ¥»º³å²¢·¢ÈÎÎñ** **µ÷ÕûºÏÊÊ**µÄ**corePoolSize**È¥ÉèÖô¦ÀíÈÎÎñµÄÏß³ÌÊý¡£ÔÚÕâÀï ÉèÖõÄ**Ïß³ÌÊý¹ý¶à**¿ÉÄÜ»¹»á**Òý·¢Ïß³ÌÉÏÏÂÎÄÇл»Æµ·±**µÄÎÊÌâ Ò²»á½µµÍ´¦ÀíÈÎÎñµÄËÙ¶È **½µµÍÍÌÍÂÁ¿**¡£
**³¡¾°3 ¶ÓÁÐÉèÖùý³¤**
ÓÉÓÚ**¶ÓÁÐÉèÖùý³¤** **×î´óÏß³ÌÊýÉèÖÃʧЧ** µ¼ÖÂÇëÇóÊýÁ¿Ôö¼Óʱ ´óÁ¿ÈÎÎñ¶Ñ»ýÔÚ¶ÓÁÐÖÐ ÈÎÎñÖ´ÐÐʱ¼ä¹ý³¤ ×îÖÕµ¼ÖÂÏÂÓηþÎñµÄ´óÁ¿µ÷Óó¬Ê±Ê§°Ü
ÄÇô¾ßÌåÊýÖµÔõôÅäÖÃÄØ
![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fddab6c4deb9441183f7102b3e84d416~tplv-k3u1fbpfcp-zoom-1.image)
¿ÉÒÔ¿´³ö ÕâЩ¼ÆË㹫ʽ¶¼Æ«ÀëÁËʵ¼ÊµÄÒµÎñ³¡¾°¡£I/OÃܼ¯ÐͺÍCPUÃܼ¯ÐͲî±ðºÜ´ó ²»¹ý¶¼¸úCPUºËÐÄÊý¹Ò¹³µÄ I/OÃܼ¯ÐÍÈÎÎñ³£³£ÐèÒªÎÒÃǽøÐÐÏ̳߳زÎÊý¶¯Ì¬»¯ ËùÓÐÏ̳߳ØÒ²·Ç³£ÓѺõÄÌṩÁË**¼¸¸ö¹«¹²·½·¨** ¹©ÎÒÃǶ¯Ì¬ÅäÖÃÏ̳߳صÄ**Ï̺߳ËÐÄÊý**ºÍ**Ïß³Ì×î´óÊý**ºÍ**×èÈû¶ÓÁдóС**¡£
³ýÁËÕâЩ ÎÒÃÇÇ°ÃæÌáµ½µÄ**¾Ü¾ø²ßÂÔ**ºÍ**ÈÎÎñÖ´ÐÐÇ°´¦Àí**ºÍ**ÈÎÎñÖ´Ðкó´¦Àí**¶¼¿ÉÒÔ×÷ΪÎÒÃǶÔÏ̳߳صÄÀ©Õ¹¡£Í¨¹ýÕâЩÅäÖà ÎÒÃÇ¿ÉÒÔʵÏÖ¶ÔÏ̳߳صĶ¯Ì¬²ÎÊýµ÷Õû ÈÎÎñÖ´ÐÐÇé¿ö ¶ÓÁиºÔØÇé¿ö ¼à¿Ø ÈÕÖ¾µÈµÈ¡£
ÕâÀï¸ø³öÈÎÎñÇ°ÖÃ/ºóÖô¦ÀíµÄÀ©Õ¹×öÒ»¸ö¼à¿Ø
java
public class TimingThreadPool extends ThreadPoolExecutor {
public TimingThreadPool() {
super(1, 1, 0L, TimeUnit.SECONDS, null);
}
private static final Logger logger LoggerFactory.getLogger(TimingThreadPool.class);
private final ThreadLocal Long startTime new ThreadLocal Long
private final AtomicLong numTasks new AtomicLong();
private final AtomicLong totalTime new AtomicLong();
Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
logger.info(String.format( Thread %s: start %s , t, r));
startTime.set(System.nanoTime());
}
Override
protected void afterExecute(Runnable r, Throwable t) {
try {
long endTime System.nanoTime();
long taskTime endTime - startTime.get();
numTasks.incrementAndGet();
totalTime.addAndGet(taskTime);
logger.info(String.format( Thread %s: end %s, time %dns ,
t, r, taskTime));
} finally {
super.afterExecute(r, t);
}
}
Override
protected void terminated() {
try {
logger.info(String.format( Terminated: avg time %dns ,
totalTime.get() / numTasks.get()));
} finally {
super.terminated();
}
}
}
#### ÑÓÉìÔĶÁ
- JDK8 : Ô´Âë
- ¡¶Java²¢·¢±à³Ìʵս¡·
- http://creativecommons.org/publicdomain/zero/1.0/
**µã¹Ø×¢ ²»ÃÔ·**
ºÃÁ˸÷λ ÒÔÉϾÍÊÇÕâƪÎÄÕµÄÈ«²¿ÄÚÈÝÁË ÄÜ¿´µ½ÕâÀïµÄÈËѽ ¶¼ÊÇÈ˲š£
ÎÒºóÃæ»áÿÖܶ¼¸üм¸ÆªÒ»Ïß»¥ÁªÍø´ó³§ÃæÊԺͳ£Óü¼ÊõÕ»Ïà¹ØµÄÎÄÕ ·Ç³£¸ÐлÈ˲ÅÃÇÄÜ¿´µ½ÕâÀï Èç¹ûÕâ¸öÎÄÕÂдµÃ»¹²»´í ¾õµÃÓе㶫Î÷µÄ»° ÇóµãÔÞ Çó¹Ø×¢?? Çó·ÖÏí ¶ÔůÄÐÎÒÀ´ËµÕæµÄ ·Ç³£ÓÐÓÃ
Èç¹û±¾Æª²©¿ÍÓÐÈκδíÎó ÇëÅúÆÀÖ¸½Ì ²»Ê¤¸Ð¼¤
ÎÄÄ©¸£Àû ×î½üÕûÀíÒ»·ÝÃæÊÔ×ÊÁÏ¡¶JavaÃæÊÔͨ¹ØÊֲᡷ ¸²¸ÇÁËJavaºËÐļ¼Êõ¡¢JVM¡¢Java²¢·¢¡¢SSM¡¢Î¢·þÎñ¡¢Êý¾Ý¿â¡¢Êý¾Ý½á¹¹µÈµÈ¡£»ñÈ¡·½Ê½ GitHub github.com/Tingyu-Note¡ ¸ü¶àÄÚÈݽÐø·îÉÏ¡£
ÉÏ´«Îļþµ½ ÔÆ·þÎñÆ÷ ÓÃʲôÈí¼þ£¿ÉÏ´«Îļþµ½ ÔÆ·þÎñÆ÷ ¿ÉÒÔʹÓÃFTP·½Ê½£¬ÔÆ·þÎñ...
ÎÊÌâ±³¾° Èç¹û¿ìËÙ·¢·ÅÂã½ðÊô·þÎñÆ÷µÄ¸ù·ÖÇø´óСÎÞ·¨Âú×ãÒµÎñÐèÇ󣬿ÉÒԲο¼±¾ÕÂ...
×÷ÕߣºÕÅÌì ÏÖÔÚ»¥ÁªÍø¼Ü¹¹Ëæ×ÅÓû§µÄÔö¼Ó£¬¶øÔ½À´Ô½¸´ÔÓ£¬¿ÉÄÜÒªÓгÉǧÉÏÍò¸ö²»...
TOPÔÆ £¨west.cn£©8ÔÂ23ÈÕÏûÏ¢£¬ÓɹúÄÚÆóҵ÷̩ŵ¹É·ÝΪÊ×µÄÖйú²ÆÍŽüÈÕÊÕ¹ºÁË...
C++ºÍJava¿ÉÄÜÊǼÆËã»ú¿ÆѧÖÐ×îÑÏÖصĴíÎó¡£Á½Õ߶¼Êܵ½ÁËOOP´´Ê¼ÈËAlan Kay±¾ÈË...
Ò».Ϊʲô»áÓÐDocker³öÏÖ Ò»¿î²úÆ·´Ó¿ª·¢µ½ÉÏÏߣ¬´Ó²Ù×÷ϵͳ£¬µ½ÔËÐл·¾³£¬ÔÙµ½...
ÄãºÃ£¬ÎÒÊÇA¸ç(YourBatman)¡£ ±¾ÏµÁеÄÄ¿µÄÊÇÃ÷Ã÷°×°×¡¢³¹³¹µ×µ×µÄ¸ã¶¨ÈÕÆÚ/ʱ¼ä...
¸Ã²Î¿¼¼Ü¹¹»ùÓÚÄ£ÐÍÇý¶¯µÄ¹¤³Ì·½·¨£¨Model-Driven Engineering£¬MDE£©½øÐÐÉè¼Æ£¬...
´óÊý¾Ý¼¼Êõ¿ÉÒÔÔÚÆóÒµµÄÕûÌå½ÌÓýÖвúÉúÈç´ËÇ¿´ó¶øÓÐÓ°ÏìÁ¦µÄ±ä»¯¡£ÕâÊǶԴËÒªÁË...
¡¾51CTO.comÔ´´¸å¼þ¡¿ÔƼÆËãƾ½èµÍ³É±¾¡¢¸ü¸ßЧµÈÓÅÊƸıäÁË»ù´¡ÉèÊ©¡¢Æ½Ì¨¡¢Ó¦...