Ï̳߳غÍThreadPoolExecutors
ËäÈ»ÔÚ³ÌÐòÖпÉÒÔÖ±½ÓʹÓÃThreadÀàÐÍÀ´½øÐÐÏ̲߳Ù×÷£¬µ«ÊǸü¶àµÄÇé¿öÊÇʹÓÃÏ̳߳أ¬ÓÈÆäÊÇÔÚJava
EEÓ¦Ó÷þÎñÆ÷ÖУ¬Ò»°ã»áʹÓÃÈô¸É¸öÏ̳߳ØÀ´´¦ÀíÀ´×Ô¿Í»§¶ËµÄÇëÇó¡£JavaÖжÔÓÚÏ̳߳صÄÖ§³Ö£¬À´×ÔThreadPoolExecutor¡£Ò»Ð©Ó¦Ó÷þÎñÆ÷ҲȷʵÊÇʹÓõÄThreadPoolExecutorÀ´ÊµÏÖÏ̳߳ء£
¶ÔÓÚÏ̳߳صÄÐÔÄܵ÷ÓÅ£¬×îÖØÒªµÄ²ÎÊý¾ÍÊÇÏ̳߳صĴóС¡£
¶ÔÓÚÈκÎÏ̳߳ضøÑÔ£¬ËüÃǵŤ×÷·½Ê½¼¸ºõ¶¼ÊÇÏàͬµÄ£º
1.ÈÎÎñ±»Í¶·Åµ½Ò»¸ö¶ÓÁÐÖÐ(¶ÓÁеÄÊýÁ¿²»¶¨)
2.Ï̴߳ӶÓÁÐÖÐÈ¡µÃÈÎÎñ²¢Ö´ÐÐ
3.Ïß³ÌÍê³ÉÈÎÎñºó£¬¼ÌÐø³¢ÊÔ´Ó¶ÓÁÐÖÐÈ¡µÃÈÎÎñ£¬Èç¹û¶ÓÁÐΪ¿Õ£¬ÄÇôÏ߳̽øÈëµÈ´ý״̬
Ï̳߳ØÍùÍùÓµÓÐ×îСºÍ×î´óÏß³ÌÊý£º
1.×îСÏß³ÌÊý£¬¼´µ±ÈÎÎñ¶ÓÁÐΪ¿Õʱ£¬Ï̳߳ØÖÐ×îÉÙÐèÒª±£³ÖµÄÏß³ÌÊýÁ¿£¬ÕâÑù×öÊÇ¿¼Âǵ½´´½¨Ïß³ÌÊÇÒ»¸öÏà¶ÔºÄ·Ñ×ÊÔ´µÄ²Ù×÷£¬Ó¦µ±¾¡¿ÉÄܵرÜÃ⣬µ±ÓÐÐÂÈÎÎñ±»Í¶Èë¶ÓÁÐʱ£¬×Ü»áÓÐÏß³ÌÄܹ»Á¢¼´¶ÔËü½øÐд¦Àí¡£
2.×î´óÏß³ÌÊý£¬µ±ÐèÒª´¦ÀíµÄÈÎÎñ¹ý¶àʱ£¬Ï̳߳ØÄܹ»ÓµÓеÄ×î´óÏß³ÌÊý¡£ÕâÑùÊÇΪÁ˱£Ö¤²»»áÓйý¶àµÄÏ̱߳»´´½¨³öÀ´£¬ÒòΪÏ̵߳ÄÔËÐÐÐèÒªÒÀÀµÓÚCPU×ÊÔ´ºÍÆäËü¸÷ÖÖ×ÊÔ´£¬µ±Ï̹߳ý¶àʱ£¬·´¶ø»á½µµÍÐÔÄÜ¡£
ÔÚThreadPoolExecutorºÍÆäÏà¹ØµÄÀàÐÍÖУ¬×îСÏß³ÌÊý±»³ÆÎªÏ̳߳غËÐĹæÄ£(Core
Pool Size)£¬ÔÚÆäËüJavaÓ¦Ó÷þÎñÆ÷µÄʵÏÖÖУ¬Õâ¸öÊýÁ¿Ò²Ðí±»³ÆÎª×îСÏß³ÌÊý(MinThreads)£¬µ«ÊÇËüÃǵĸÅÄîÊÇÏàͬµÄ¡£
µ«ÊÇÔÚ¶ÔÏ̳߳ؽøÐйæÄ£±ä¸ü(Resizing)µÄʱºò£¬ThreadPoolExecutorºÍÆäËüÏ̳߳صÄʵÏÖÒ²Ðí´æÔڵĺܴóµÄ²î±ð¡£
Ò»¸ö×î¼òµ¥µÄÇé¿öÊÇ£ºµ±ÓÐÐÂÈÎÎñÐèÒª±»Ö´ÐУ¬ÇÒµ±Ç°ËùÓеÄÏ̶߳¼±»Õ¼ÓÃʱ£¬ThreadPoolExecutorºÍÆäËüʵÏÖͨ³£¶¼»áд´½¨Ò»¸öÏß³ÌÀ´Ö´ÐÐÕâ¸öÐÂÈÎÎñ(Ö±µ½´ïµ½ÁË×î´óÏß³ÌÊý)¡£
ÉèÖÃ×î´óÏß³ÌÊý
×îºÏÊʵÄ×î´óÏß³ÌÊý¸ÃÔõôȷ¶¨£¬ÒÀÀµÒÔÏÂÁ½¸ö·½Ã棺
1.ÈÎÎñµÄÌØÕ÷
2.¼ÆËã»úµÄÓ²¼þÇé¿ö
ΪÁË·½±ãÌÖÂÛ£¬ÏÂÃæ¼ÙÉèJVMÓÐ4¸ö¿ÉÓõÄCPU¡£ÄÇôÈÎÎñÒ²ºÜÃ÷È·£¬¾ÍÊÇÒª×î´ó³Ì¶ÈµØ¡°Ñ¹Õ¥¡±ËüÃǵÄ×ÊÔ´£¬Ç§·½°Ù¼ÆµÄÌá¸ßCPUµÄÀûÓÃÂÊ¡£
ÄÇô£¬×î´óÏß³ÌÊý×îÉÙÐèÒª±»ÉèÖóÉ4£¬ÒòΪÓÐ4¸ö¿ÉÓõÄCPU£¬Òâζ×Å×î¶àÄܹ»²¢ÐеØÖ´ÐÐ4¸öÈÎÎñ¡£µ±È»£¬À¬»ø»ØÊÕ(Garbage
Collection)ÔÚÕâ¸ö¹ý³ÌÖÐÒ²»áÔì³ÉһЩӰÏ죬µ«ÊÇËüÃÇÍùÍù²»ÐèҪʹÓÃÕû¸öCPU¡£Ò»¸öÀýÍâÊÇ£¬µ±Ê¹ÓÃÁËCMS»òÕßG1À¬»ø»ØÊÕË㷨ʱ£¬ÐèÒªÓÐ×ã¹»µÄCPU×ÊÔ´½øÐÐÀ¬»ø»ØÊÕ¡£
ÄÇôÊÇ·ñÓбØÒª½«Ïß³ÌÊýÁ¿ÉèÖõĸü´óÄØ£¿Õâ¾ÍÈ¡¾öÓÚÈÎÎñµÄÌØÕ÷ÁË¡£
¼ÙÉèµ±ÈÎÎñÊǼÆËãÃܼ¯Ð͵ģ¬Òâζ×ÅÈÎÎñ²»ÐèÒªÖ´ÐÐIO²Ù×÷£¬ÀýÈç¶ÁÈ¡Êý¾Ý¿â£¬¶ÁÈ¡ÎļþµÈ£¬Òò´ËËüÃDz»Éæ¼°µ½Í¬²½µÄÎÊÌ⣬ÈÎÎñÖ®¼äÍêÈ«ÊǶÀÁ¢µÄ¡£±ÈÈçʹÓÃÒ»¸öÅú´¦Àí³ÌÐò¶ÁÈ¡MockÊý¾ÝÔ´µÄÊý¾Ý£¬²âÊÔÔÚ²»Ï̳߳ØÓµÓв»Í¬Ïß³ÌÊýÁ¿Ê±µÄÐÔÄÜ£¬µÃµ½ÏÂ±í£º

´ÓÉÏÃæÖеõ½Ò»Ð©½áÂÛ£º
1.µ±Ïß³ÌÊýΪ4ʱ£¬´ïµ½×îÓÅÐÔÄÜ£¬ÔÙÔö¼ÓÏß³ÌÊýÁ¿Ê±²¢Ã»ÓиüºÃµÄÐÔÄÜ£¬ÒòΪ´ËʱCPUµÄÀûÓÃÂÊÒѾ´ïµ½ÁË×î¸ß£¬ÔÚÔö¼ÓÏß³ÌÖ»»áÔö¼ÓÏß³ÌÖ®¼äÕù¶áCPU×ÊÔ´µÄÐÐΪ£¬Òò´Ë·´¶ø½µµÍÁËÐÔÄÜ¡£
2.¼´Ê¹ÔÚCPUÀûÓÃÂÊ´ïµ½×î¸ßʱ£¬»ùÏß°Ù·Ö±ÈÒ²²»ÊÇÀíÏëÖеÄ25%£¬ÕâÊÇÒòΪËäÈ»ÔÚ³ÌÐòÔËÐйý³ÌÖУ¬CPU×ÊÔ´²¢²»ÊÇÖ»±»Ó¦ÓóÌÐòÏ̶߳ÀÏíµÄ£¬Ò»Ð©ºǫ́Ïß³ÌÓÐʱҲ»áÐèÒªCPU×ÊÔ´£¬±ÈÈçGCÏ̺߳ÍϵͳµÄһЩÏ̵߳ȡ£
µ±¼ÆËãÊÇͨ¹ýServlet´¥·¢µÄʱºò£¬ÐÔÄÜÊý¾ÝÊÇÏÂÃæÕâ¸öÑù×ÓµÄ(Load
Generator»áͬʱ·¢ËÍ20¸öÇëÇó)£º

´ÓÉϱíÖпÉÒԵõ½µÄ½áÂÛ£º
1.ÔÚÏß³ÌÊýÁ¿Îª4ʱ£¬ÐÔÄÜ×îÓÅ¡£ÒòΪ´ËÈÎÎñµÄÀàÐÍÊǼÆËãÃܼ¯Ð͵ģ¬Ö»ÓÐ4¸öCPU£¬Òò´ËÏß³ÌÊýÁ¿Îª4ʱ£¬´ïµ½×îÓÅÇé¿ö¡£
2.Ëæ×ÅÏß³ÌÊýÁ¿Öð½¥Ôö¼Ó£¬ÐÔÄÜϽµ£¬ÒòΪÏß³ÌÖ®¼ä»á»¥ÏàÕù¶áCPU×ÊÔ´£¬Ôì³ÉƵ·±Çл»Ïß³ÌÖ´ÐÐÉÏÏÂÎÄ»·¾³£¬¶øÕâЩÇл»Ö»»áÀË·ÑCPU×ÊÔ´¡£
3.ÐÔÄÜϽµµÄËٶȲ¢²»Ã÷ÏÔ£¬ÕâÒ²ÊÇÒòΪÈÎÎñÀàÐÍÊǼÆËãÃܼ¯Ð͵ÄÔµ¹Ê£¬Èç¹ûÐÔÄÜÆ¿¾±²»ÊÇCPUÌṩµÄ¼ÆËã×ÊÔ´£¬¶øÊÇÍⲿµÄ×ÊÔ´£¬ÈçÊý¾Ý¿â£¬Îļþ²Ù×÷µÈ£¬ÄÇôÔö¼ÓÏß³ÌÊýÁ¿´øÀ´µÄÐÔÄÜϽµÒ²Ðí»á¸ü¼ÓÃ÷ÏÔ¡£
ÏÂÃæ£¬´ÓClientµÄ½Ç¶È¿¼ÂÇÒ»ÏÂÎÊÌ⣬²¢·¢ClientµÄÊýÁ¿¶ÔÓÚServerµÄÏìӦʱ¼ä»áÓÐʲôӰÏìÄØ£¿»¹ÊÇͬÑùµØ»·¾³£¬µ±²¢·¢ClientÊýÁ¿Öð½¥Ôö¼Óʱ£¬ÏìӦʱ¼ä»áÈçÏ·¢Éú±ä»¯£º

ÒòΪÈÎÎñÀàÐÍÊǼÆËãÃܼ¯Ð͵쬵±²¢·¢ClientÊýÁ¿Ê±1£¬2£¬4ʱ£¬Æ½¾ùÏìӦʱ¼ä¶¼ÊÇ×îÓŵģ¬È»¶øµ±³öÏÖ¶àÓà4¸öClientʱ£¬ÐÔÄÜ»áËæ×ÅClientµÄÔö¼Ó·¢ÉúÏÔÖøµØÏ½µ¡£
µ±ClientÊýÁ¿Ôö¼Óʱ£¬ÄãÒ²Ðí»áÏëͨ¹ýÔö¼Ó·þÎñ¶ËÏ̳߳صÄÏß³ÌÊýÁ¿À´Ìá¸ßÐÔÄÜ£¬¿ÉÊÇÔÚCPUÃܼ¯ÐÍÈÎÎñµÄÇé¿öÏ£¬Õâô×öÖ»»á½µµÍÐÔÄÜ¡£ÒòΪϵͳµÄÆ¿¾±¾ÍÊÇCPU×ÊÔ´£¬Ã°È»Ôö¼ÓÏ̳߳صÄÏß³ÌÊýÁ¿Ö»»áÈöÔÓÚÕâÖÖ×ÊÔ´µÄ¾ºÕù¸ü¼Ó¼¤ÁÒ¡£
ËùÒÔ£¬ÔÚÃæ¶ÔÐÔÄÜ·½ÃæµÄÎÊÌâʱ¡£µÚÒ»²½ÓÀÔ¶ÊÇÁ˽âϵͳµÄÆ¿¾±ÔÚÄÄÀÕâÑù²ÅÄܹ»ÓеķÅʸ¡£Èç¹ûðȻ½øÐÐËùνµÄ¡°µ÷ÓÅ¡±£¬ÈÃ¶ÔÆ¿¾±×ÊÔ´µÄ¾ºÕù¸ü¼Ó¼¤ÁÒ£¬ÄÇô´øÀ´µÄÖ»»áÊÇÐÔÄܵĽøÒ»²½Ï½µ¡£Ïà·´£¬Èç¹ûÈÃ¶ÔÆ¿¾±×ÊÔ´µÄ¾ºÕù±äµÄ»ººÍ£¬ÄÇôÐÔÄÜͨ³£Ôò»áÌá¸ß¡£
ÔÚÉÏÃæµÄ³¡¾°ÖУ¬Èç¹û´ÓThreadPoolExecutorµÄ½Ç¶È½øÐп¼ÂÇ£¬ÄÇôÔÚÈÎÎñ¶ÓÁÐÖÐÒ»Ö±»áÓÐÈÎÎñ´¦ÓÚ¹ÒÆð(Pending)µÄ״̬(ÒòΪClientµÄÿ¸öÇëÇó¶ÔÓ¦µÄ¾ÍÊÇÒ»¸öÈÎÎñ)£¬¶øËùÓеĿÉÓÃÏ̶߳¼ÔÚ¹¤×÷£¬CPUÕýÔÚÂú¸ººÉÔËת¡£Õâ¸öʱºòÌí¼ÓÏ̳߳صÄÏß³ÌÊýÁ¿£¬ÈÃÕâЩÌí¼ÓµÄÏß³ÌÁìȡһЩ¹ÒÆðµÄÈÎÎñ£¬»á·¢ÉúʲôÊÂÇéÄØ£¿Õâʱ´øÀ´µÄÖ»»áÊÇÏß³ÌÖ®¼ä¶ÔÓÚCPU×ÊÔ´µÄÕù¶á¸ü¼Ó¼¤ÁÒ£¬½µµÍÁËÐÔÄÜ¡£
ÉèÖÃ×îСÏß³ÌÊý
ÉèÖÃÁË×î´óÏß³ÌÊýÖ®ºó£¬»¹ÐèÒªÉèÖÃ×îСÏß³ÌÊý¡£¶ÔÓÚ¾ø´ó²¿·Ö³¡¾°£¬½«ËüÉèÖõĺÍ×î´óÏß³ÌÊýÏàµÈ¾Í¿ÉÒÔÁË¡£
½«×îСÏß³ÌÊýÉèÖõÄСÓÚ×î´óÏß³ÌÊýµÄ³õÖÔÊÇΪÁ˽ÚÊ¡×ÊÔ´£¬ÒòΪÿ¶à´´½¨Ò»¸öÏ̶߳¼»áºÄ·ÑÒ»¶¨Á¿µÄ×ÊÔ´£¬ÓÈÆäÊÇÏß³ÌÕ»ËùÐèÒªµÄ×ÊÔ´¡£µ«ÊÇÔÚÒ»¸öϵͳÖУ¬Õë¶ÔÓ²¼þ×ÊÔ´ÒÔ¼°ÈÎÎñÌØµãÑ¡¶¨ÁË×î´óÏß³ÌÊýÖ®ºó£¬¾Í±íʾÕâ¸öϵͳ×ÜÊÇ»áÀûÓÃÕâЩÏ̵߳ģ¬ÄÇô»¹²»ÈçÔÚÒ»¿ªÊ¼¾ÍÈÃÏ̳߳ذÑÐèÒªµÄÏß³Ì×¼±¸ºÃ¡£È»¶ø£¬°Ñ×îСÏß³ÌÊýÉèÖõÄСÓÚ×î´óÏß³ÌÊýËù´øÀ´µÄÓ°ÏìÒ²ÊǷdz£Ð¡µÄ£¬Ò»°ã¶¼²»»á²ì¾õµ½ÓÐʲô²»Í¬¡£
ÔÚÅú´¦Àí³ÌÐòÖУ¬×îСÏß³ÌÊýÊÇ·ñµÈÓÚ×î´óÏß³ÌÊý²¢²»ÖØÒª¡£ÒòΪ×îºóÏß³Ì×ÜÊÇÐèÒª±»´´½¨³öÀ´µÄ£¬ËùÒÔ³ÌÐòµÄÔËÐÐʱ¼äÓ¦¸Ã¼¸ºõÏàͬ¡£¶ÔÓÚ·þÎñÆ÷³ÌÐò¶øÑÔ£¬Ó°ÏìÒ²²»´ó£¬µ«ÊÇÒ»°ã¶øÑÔ£¬Ï̳߳ØÖеÄÏß³ÌÔÚ¡°ÈÈÉí¡±½×¶Î¾ÍÓ¦¸Ã±»´´½¨³öÀ´£¬ËùÒÔÕâÒ²ÊÇΪʲô½¨Ò齫×îСÏß³ÌÊýÉèÖõĵÈÓÚ×î´óÏß³ÌÊýµÄÔÒò¡£
ÔÚһЩ³¡¾°ÖУ¬Ò²ÐèÒªÒªÉèÖÃÒ»¸ö²»Í¬µÄ×îСÏß³ÌÊý¡£±ÈÈçµ±Ò»¸öϵͳ×î´óÐèҪͬʱ´¦Àí2000¸öÈÎÎñ£¬¶øÆ½¾ùÈÎÎñÊýÁ¿Ö»ÊÇ20¸öÇé¿öÏ£¬¾ÍÐèÒª½«×îСÏß³ÌÊýÉèÖóÉ20£¬¶ø²»ÊǵÈÓÚÆä×î´óÏß³ÌÊý2000¡£´ËʱÈç¹û»¹Êǽ«×îСÏß³ÌÊýÉèÖõĵÈÓÚ×î´óÏß³ÌÊýµÄ»°£¬ÄÇôÏÐÖÃÏß³Ì(Idle
Thread)Õ¼ÓõÄ×ÊÔ´¾Í±È½Ï¿É¹ÛÁË£¬ÓÈÆäÊǵ±Ê¹ÓÃÁËThreadLocalÀàÐ͵ıäÁ¿Ê±¡£
Ï̳߳ØÈÎÎñÊýÁ¿(Thread Pool Task Sizes)
Ï̳߳ØÓÐÒ»¸öÁбí»òÕß¶ÓÁеÄÊý¾Ý½á¹¹À´´æ·ÅÐèÒª±»Ö´ÐеÄÈÎÎñ¡£ÏÔÈ»£¬ÔÚijЩÇé¿öÏ£¬ÈÎÎñÊýÁ¿µÄÔö³¤ËÙ¶È»á´óÓÚÆä±»Ö´ÐеÄËÙ¶È¡£Èç¹ûÕâ¸öÈÎÎñ´ú±íµÄÊÇÒ»¸öÀ´×ÔClientµÄÇëÇó£¬ÄÇôҲ¾ÍÒâζןÃClient»áµÈ´ý±È½Ï³¤µÄʱ¼ä¡£ÏÔÈ»ÕâÊDz»¿É½ÓÊܵģ¬ÓÈÆä¶ÔÓÚÌṩWeb·þÎñµÄ·þÎñÆ÷³ÌÐò¶øÑÔ¡£
ËùÒÔ£¬Ï̳߳ػáÓлúÖÆÀ´ÏÞÖÆÁбí/¶ÓÁÐÖÐÈÎÎñµÄÊýÁ¿¡£µ«ÊÇ£¬ºÍÉèÖÃ×î´óÏß³ÌÊýÒ»Ñù£¬²¢Ã»ÓÐÒ»¸ö·ÅÖ®Ëĺ£¶ø½Ô×¼µÄ×îÓÅÈÎÎñÊýÁ¿¡£Õ⻹ÊÇҪȡ¾öÓÚ¾ßÌåµÄÈÎÎñÀàÐͺͲ»¶ÏµÄ½øÐÐÐÔÄܲâÊÔ¡£
¶ÔÓÚThreadPoolExecutor¶øÑÔ£¬µ±ÈÎÎñÊýÁ¿´ïµ½×î´óʱ£¬ÔÙ³¢ÊÔÔö¼ÓеÄÈÎÎñ¾Í»áʧ°Ü¡£ThreadPoolExecutorÓÐÒ»¸örejectedExecution·½·¨ÓÃÀ´¾Ü¾ø¸ÃÈÎÎñ¡£Õâ»áµ¼ÖÂÓ¦Ó÷þÎñÆ÷·µ»ØÒ»¸öHTTP״̬Âë500£¬µ±È»ÕâÖÖÐÅÏ¢×îºÃÒÔ¸üÓѺõķ½Ê½´«´ï¸øClient£¬±ÈÈç½âÊÍÒ»ÏÂΪʲôÄãµÄÇëÇ󱻾ܾøÁË¡£
¶¨ÖÆThreadPoolExecutor
Ï̳߳ØÔÚͬʱÂú×ãÒÔÏÂÈý¸öÌõ¼þʱ£¬¾Í»á´´½¨Ò»¸öеÄỊ̈߳º
1.ÓÐÈÎÎñÐèÒª±»Ö´ÐÐ
2.µ±Ç°Ï̳߳ØÖÐËùÓеÄÏ̶߳¼´¦ÓÚ¹¤×÷״̬
3.µ±Ç°Ï̳߳صÄÏß³ÌÊýûÓдﵽ×î´óÏß³ÌÊý
ÖÁÓÚÏ̳߳ػáÈçºÎ´´½¨Õâ¸öеÄỊ̈߳¬ÔòÊǸù¾ÝÈÎÎñ¶ÓÁеÄÖÖÀࣺ
1.ÈÎÎñ¶ÓÁÐÊÇ SynchronousQueue Õâ¸ö¶ÓÁеÄÌØµãÊÇ£¬Ëü²¢²»ÄÜ·ÅÖÃÈκÎÈÎÎñÔÚÆä¶ÓÁÐÖУ¬µ±ÓÐÈÎÎñ±»Ìύʱ£¬Ê¹ÓÃSynchronousQueueµÄÏ̳߳ػáÁ¢¼´Îª¸ÃÈÎÎñ´´½¨Ò»¸öÏß³Ì(Èç¹ûÏß³ÌÊýÁ¿Ã»Óдﵽ×î´óʱ£¬Èç¹û´ïµ½ÁË×î´ó£¬ÄÇô¸ÃÈÎÎñ»á±»¾Ü¾ø)¡£ÕâÖÖ¶ÓÁÐÊʺÏÓÚµ±ÈÎÎñÊýÁ¿½ÏСʱ²ÉÓá£Ò²¾ÍÊÇ˵£¬ÔÚʹÓÃÕâÖÖ¶ÓÁÐʱ£¬Î´±»Ö´ÐеÄÈÎÎñûÓÐÒ»¸öÈÝÆ÷À´ÔÝʱ´¢´æ¡£
2.ÈÎÎñ¶ÓÁÐÊÇ ÎÞÏÞ¶ÓÁÐ(Unbound Queue) ÎÞ½çÏ޵ĶÓÁпÉÒÔÊÇÖîÈçLinkedBlockingQueueÕâÖÖÀàÐÍ£¬ÔÚÕâÖÖÇé¿öÏ£¬Èκα»Ìá½»µÄÈÎÎñ¶¼²»»á±»¾Ü¾ø¡£µ«ÊÇÏ̳߳ػáºöÂÔ×î´óÏß³ÌÊýÕâÒ»²ÎÊý£¬Òâζ×ÅÏ̳߳صÄ×î´óÏß³ÌÊý¾Í±ä³ÉÁËÉèÖõÄ×îСÏß³ÌÊý¡£ËùÒÔÔÚʹÓÃÕâÖÖ¶ÓÁÐʱ£¬Í¨³£»á½«×î´óÏß³ÌÊýÉèÖõĺÍ×îСÏß³ÌÊýÏàµÈ¡£Õâ¾ÍÏ൱ÓÚʹÓÃÁËÒ»¸ö¹Ì¶¨ÁËÏß³ÌÊýÁ¿µÄÏ̳߳ء£
3.ÈÎÎñ¶ÓÁÐÊÇ ÓÐÏÞ¶ÓÁÐ(Bounded Queue) µ±Ê¹ÓõĶÓÁÐÊÇÖîÈçArrayBlockingQueueÕâÖÖÓÐÏÞ¶ÓÁеÄʱºò£¬À´¾ö¶¨Ê²Ã´Ê±ºò´´½¨ÐÂÏ̵߳ÄËã·¨¾ÍÏà¶Ô¸´ÔÓһЩÁË¡£±ÈÈ磬×îСÏß³ÌÊýÊÇ4£¬×î´óÏß³ÌÊýÊÇ8£¬ÈÎÎñ¶ÓÁÐ×î¶àÄܹ»ÈÝÄÉ10¸öÈÎÎñ¡£ÔÚÕâÖÖÇé¿öÏ£¬µ±ÈÎÎñÖð½¥±»Ìí¼Óµ½¶ÓÁÐÖУ¬Ö±µ½¶ÓÁб»Õ¼Âú(10¸öÈÎÎñ)£¬´ËʱÏ̳߳ØÖеŤ×÷Ïß³ÌÈÔȻֻÓÐ4¸ö£¬¼´×îСÏß³ÌÊý¡£Ö»Óе±ÈÔÈ»ÓÐÈÎÎñÏ£Íû±»·ÅÖõ½¶ÓÁÐÖеÄʱºò£¬Ï̳߳زŻáд´½¨Ò»¸öÏ̲߳¢´Ó¶ÓÁÐÍ·²¿ÄÃ×ßÒ»¸öÈÎÎñ£¬ÒÔÌÚ³öλÖÃÀ´ÈÝÄÉÕâ¸ö×îб»Ìá½»µÄÈÎÎñ¡£
¹ØÓÚÈçºÎ¶¨ÖÆThreadPoolExecutor£¬×ñÑKISSÔÔò(Keep It Simple, Stupid)¾ÍºÃÁË¡£±ÈÈ罫×î´óÏß³ÌÊýºÍ×îСÏß³ÌÊýÉèÖõÄÏàµÈ£¬È»ºó¸ù¾ÝÇé¿öÑ¡ÔñÓÐÏÞ¶ÓÁлòÕßÎÞÏÞ¶ÓÁС£
×ܽá
1.Ï̳߳ØÊǶÔÏ󳨵ÄÒ»¸öÓÐÓõÄÀý×Ó£¬ËüÄܹ»½ÚÊ¡ÔÚ´´½¨ËüÃÇʱºòµÄ×ÊÔ´¿ªÏú¡£²¢ÇÒÏ̳߳ضÔϵͳÖеÄÏß³ÌÊýÁ¿Ò²Æðµ½Á˺ܺõÄÏÞÖÆ×÷Óá£
2.Ï̳߳ØÖеÄÏß³ÌÊýÁ¿±ØÐë×ÐϸµÄÉèÖ㬷ñÔòðȻÔö¼ÓÏß³ÌÊýÁ¿Ö»»á´øÀ´ÐÔÄܵÄϽµ¡£
3.ÔÚ¶¨ÖÆThreadPoolExecutorʱ£¬×ñÑKISSÔÔò£¬Í¨³£Çé¿öÏ»áÌṩ×îºÃµÄÐÔÄÜ¡£
ForkJoinPool
ÔÚJava 7ÖÐÒýÈëÁËÒ»ÖÖеÄÏ̳߳أºForkJoinPool¡£
ËüͬThreadPoolExecutorÒ»Ñù£¬Ò²ÊµÏÖÁËExecutorºÍExecutorService½Ó¿Ú¡£ËüʹÓÃÁËÒ»¸öÎÞÏÞ¶ÓÁÐÀ´±£´æÐèÒªÖ´ÐеÄÈÎÎñ£¬¶øÏ̵߳ÄÊýÁ¿ÔòÊÇͨ¹ý¹¹Ô캯Êý´«È룬Èç¹ûûÓÐÏò¹¹Ô캯ÊýÖд«ÈëÏ£ÍûµÄÏß³ÌÊýÁ¿£¬ÄÇôµ±Ç°¼ÆËã»ú¿ÉÓõÄCPUÊýÁ¿»á±»ÉèÖÃΪÏß³ÌÊýÁ¿×÷ΪĬÈÏÖµ¡£
ForkJoinPoolÖ÷ÒªÓÃÀ´Ê¹Ó÷ÖÖη¨(Divide-and-Conquer Algorithm)À´½â¾öÎÊÌâ¡£µäÐ͵ÄÓ¦ÓñÈÈç¿ìËÙÅÅÐòËã·¨¡£ÕâÀïµÄÒªµãÔÚÓÚ£¬ForkJoinPoolÐèҪʹÓÃÏà¶ÔÉÙµÄÏß³ÌÀ´´¦Àí´óÁ¿µÄÈÎÎñ¡£±ÈÈçÒª¶Ô1000Íò¸öÊý¾Ý½øÐÐÅÅÐò£¬ÄÇô»á½«Õâ¸öÈÎÎñ·Ö¸î³ÉÁ½¸ö500ÍòµÄÅÅÐòÈÎÎñºÍÒ»¸öÕë¶ÔÕâÁ½×é500ÍòÊý¾ÝµÄºÏ²¢ÈÎÎñ¡£ÒÔ´ËÀàÍÆ£¬¶ÔÓÚ500ÍòµÄÊý¾ÝÒ²»á×ö³öͬÑùµÄ·Ö¸î´¦Àí£¬µ½×îºó»áÉèÖÃÒ»¸öãÐÖµÀ´¹æ¶¨µ±Êý¾Ý¹æÄ£µ½¶àÉÙʱ£¬Í£Ö¹ÕâÑùµÄ·Ö¸î´¦Àí¡£±ÈÈ磬µ±ÔªËصÄÊýÁ¿Ð¡ÓÚ10ʱ£¬»áÍ£Ö¹·Ö¸î£¬×ª¶øÊ¹ÓòåÈëÅÅÐò¶ÔËüÃǽøÐÐÅÅÐò¡£
ÄÇôµ½×îºó£¬ËùÓеÄÈÎÎñ¼ÓÆðÀ´»áÓдó¸Å2000000+¸ö¡£ÎÊÌâµÄ¹Ø¼üÔÚÓÚ£¬¶ÔÓÚÒ»¸öÈÎÎñ¶øÑÔ£¬Ö»Óе±ËüËùÓеÄ×ÓÈÎÎñÍê³ÉÖ®ºó£¬Ëü²ÅÄܹ»±»Ö´ÐС£
ËùÒÔµ±Ê¹ÓÃThreadPoolExecutorʱ£¬Ê¹Ó÷ÖÖη¨»á´æÔÚÎÊÌ⣬ÒòΪThreadPoolExecutorÖеÄÏß³ÌÎÞ·¨ÏñÈÎÎñ¶ÓÁÐÖÐÔÙÌí¼ÓÒ»¸öÈÎÎñ²¢ÇÒÔڵȴý¸ÃÈÎÎñÍê³ÉÖ®ºóÔÙ¼ÌÐøÖ´ÐС£¶øÊ¹ÓÃForkJoinPoolʱ£¬¾ÍÄܹ»ÈÃÆäÖеÄÏ̴߳´½¨ÐµÄÈÎÎñ£¬²¢¹ÒÆðµ±Ç°µÄÈÎÎñ£¬´ËʱÏ߳̾ÍÄܹ»´Ó¶ÓÁÐÖÐÑ¡Ôñ×ÓÈÎÎñÖ´ÐС£
±ÈÈ磬ÎÒÃÇÐèҪͳ¼ÆÒ»¸ödoubleÊý×éÖÐСÓÚ0.5µÄÔªËØµÄ¸öÊý£¬ÄÇô¿ÉÒÔʹÓÃForkJoinPool½øÐÐʵÏÖÈçÏ£º
public class ForkJoinTest { private double[] d; private class ForkJoinTask extends RecursiveTask<Integer> { private int first; private int last; public ForkJoinTask(int first, int last) { this.first = first; this.last = last; } protected Integer compute() { int subCount; if (last - first < 10) { subCount = 0; for (int i = first; i <= last; i++) { if (d[i] < 0.5) subCount++; } } else { int mid = (first + last) >>> 1; ForkJoinTask left = new ForkJoinTask(first, mid); left.fork(); ForkJoinTask right = new ForkJoinTask(mid + 1, last); right.fork(); subCount = left.join(); subCount += right.join(); } return subCount; } } public static void main(String[] args) { d = createArrayOfRandomDoubles(); int n = new ForkJoinPool().invoke(new ForkJoinTask(0, 9999999)); System.out.println("Found " + n + " values"); } } |
ÒÔÉϵĹؼüÊÇfork()ºÍjoin()·½·¨¡£ÔÚForkJoinPoolʹÓõÄÏß³ÌÖУ¬»áʹÓÃÒ»¸öÄÚ²¿¶ÓÁÐÀ´¶ÔÐèÒªÖ´ÐеÄÈÎÎñÒÔ¼°×ÓÈÎÎñ½øÐвÙ×÷À´±£Ö¤ËüÃǵÄÖ´ÐÐ˳Ðò¡£
ÄÇôʹÓÃThreadPoolExecutor»òÕßForkJoinPool£¬»áÓÐʲôÐÔÄܵIJîÒìÄØ£¿
Ê×ÏÈ£¬Ê¹ÓÃForkJoinPoolÄܹ»Ê¹ÓÃÊýÁ¿ÓÐÏÞµÄÏß³ÌÀ´Íê³É·Ç³£¶àµÄ¾ßÓи¸×Ó¹ØÏµµÄÈÎÎñ£¬±ÈÈçʹÓÃ4¸öÏß³ÌÀ´Íê³É³¬¹ý200Íò¸öÈÎÎñ¡£µ«ÊÇ£¬Ê¹ÓÃThreadPoolExecutorʱ£¬ÊDz»¿ÉÄÜÍê³ÉµÄ£¬ÒòΪThreadPoolExecutorÖеÄThreadÎÞ·¨Ñ¡ÔñÓÅÏÈÖ´ÐÐ×ÓÈÎÎñ£¬ÐèÒªÍê³É200Íò¸ö¾ßÓи¸×Ó¹ØÏµµÄÈÎÎñʱ£¬Ò²ÐèÒª200Íò¸öỊ̈߳¬ÏÔÈ»ÕâÊDz»¿ÉÐеġ£
µ±È»£¬ÔÚÉÏÃæµÄÀý×ÓÖУ¬Ò²¿ÉÒÔ²»Ê¹Ó÷ÖÖ稣¬ÒòΪÈÎÎñÖ®¼äµÄ¶ÀÁ¢ÐÔ£¬¿ÉÒÔ½«Õû¸öÊý×é»®·ÖΪ¼¸¸öÇøÓò£¬È»ºóʹÓÃThreadPoolExecutorÀ´½â¾ö£¬ÕâÖÖ°ì·¨²»»á´´½¨ÊýÁ¿ÅÓ´óµÄ×ÓÈÎÎñ¡£´úÂëÈçÏ£º
public class ThreadPoolTest { private double[] d; private class ThreadPoolExecutorTask implements Callable<Integer> { private int first; private int last; public ThreadPoolExecutorTask(int first, int last) { this.first = first; this.last = last; } public Integer call() { int subCount = 0; for (int i = first; i <= last; i++) { if (d[i] < 0.5) { subCount++; } } return subCount; } } public static void main(String[] args) { d = createArrayOfRandomDoubles(); ThreadPoolExecutor tpe = new ThreadPoolExecutor
(4, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new LinkedBlockingQueue()); Future[] f = new Future[4]; int size = d.length / 4; for (int i = 0; i < 3; i++) { f[i] = tpe.submit(new ThreadPoolExecutorTask(i * size, (i + 1) * size - 1); } f[3] = tpe.submit(new ThreadPoolExecutorTask(3 * size, d.length - 1); int n = 0; for (int i = 0; i < 4; i++) { n += f.get(); } System.out.println("Found " + n + " values"); } } |
ÔÚ·Ö±ðʹÓÃForkJoinPoolºÍThreadPoolExecutorʱ£¬ËüÃÇ´¦ÀíÕâ¸öÎÊÌâµÄʱ¼äÈçÏ£º

¶ÔÖ´Ðйý³ÌÖеÄGCͬÑùÒ²½øÐÐÁË¼à¿Ø£¬·¢ÏÖÔÚʹÓÃForkJoinPoolʱ£¬×ܵÄGCʱ¼ä»¨È¥ÁË1.2s£¬¶øThreadPoolExecutor²¢Ã»Óд¥·¢ÈκεÄGC²Ù×÷¡£ÕâÊÇÒòΪÔÚForkJoinPoolµÄÔËÐйý³ÌÖУ¬»á´´½¨´óÁ¿µÄ×ÓÈÎÎñ¡£¶øµ±ËûÃÇÖ´ÐÐÍê±ÏÖ®ºó£¬»á±»À¬»ø»ØÊÕ¡£·´Ö®£¬ThreadPoolExecutorÔò²»»á´´½¨ÈκεÄ×ÓÈÎÎñ£¬Òò´Ë²»»áµ¼ÖÂÈκεÄGC²Ù×÷¡£
ForkJoinPoolµÄÁíÍâÒ»¸öÌØÐÔÊÇËüÄܹ»ÊµÏÖ¹¤×÷ÇÔÈ¡(Work Stealing)£¬ÔÚ¸ÃÏ̳߳صÄÿ¸öÏß³ÌÖлáά»¤Ò»¸ö¶ÓÁÐÀ´´æ·ÅÐèÒª±»Ö´ÐеÄÈÎÎñ¡£µ±Ïß³Ì×ÔÉí¶ÓÁÐÖеÄÈÎÎñ¶¼Ö´ÐÐÍê±Ïºó£¬Ëü»á´Ó±ðµÄÏß³ÌÖÐÄõ½Î´±»Ö´ÐеÄÈÎÎñ²¢°ïÖúËüÖ´ÐС£
¿ÉÒÔͨ¹ýÒÔϵĴúÂëÀ´²âÊÔForkJoinPoolµÄWork StealingÌØÐÔ£º
for (int i = first; i <= last; i++) { if (d[i] < 0.5) { subCount++; } for (int j = 0; j < d.length - i; j++) { for (int k = 0; k < 100; k++) { dummy = j * k + i; // dummy is volatile, so multiple writes occur d[i] = dummy; } } } |
ÒòΪÀï²ãµÄÑ»·´ÎÊý(j)ÊÇÒÀÀµÓÚÍâ²ãµÄiµÄÖµµÄ£¬ËùÒÔÕâ¶Î´úÂëµÄÖ´ÐÐʱ¼äÒÀÀµÓÚiµÄÖµ¡£µ±i = 0ʱ£¬Ö´ÐÐʱ¼ä×£¬¶øi
= lastʱִÐÐʱ¼ä×î¶Ì¡£Ò²¾ÍÒâζ×ÅÈÎÎñµÄ¹¤×÷Á¿ÊDz»Ò»ÑùµÄ£¬µ±iµÄÖµ½ÏСʱ£¬ÈÎÎñµÄ¹¤×÷Á¿´ó£¬Ëæ×ÅiÖð½¥Ôö¼Ó£¬ÈÎÎñµÄ¹¤×÷Á¿±äС¡£Òò´ËÕâÊÇÒ»¸öµäÐ͵ÄÈÎÎñ¸ºÔز»¾ùºâµÄ³¡¾°¡£
Õâʱ£¬Ñ¡ÔñThreadPoolExecutor¾Í²»ºÏÊÊÁË£¬ÒòΪËüÆäÖеÄÏ̲߳¢²»»á¹Ø×¢Ã¿¸öÈÎÎñÖ®¼äÈÎÎñÁ¿µÄ²îÒì¡£µ±Ö´ÐÐÈÎÎñÁ¿×îСµÄÈÎÎñµÄÏß³ÌÖ´ÐÐÍê±Ïºó£¬Ëü¾Í»á´¦ÓÚ¿ÕÏеÄ״̬(Idle)£¬µÈ´ýÈÎÎñÁ¿×î´óµÄÈÎÎñÖ´ÐÐÍê±Ï¡£
¶øForkJoinPoolµÄÇé¿ö¾Í²»Í¬ÁË£¬¼´Ê¹ÈÎÎñµÄ¹¤×÷Á¿Óвî±ð£¬µ±Ä³¸öÏß³ÌÔÚÖ´Ðй¤×÷Á¿´óµÄÈÎÎñʱ£¬ÆäËûµÄ¿ÕÏÐÏ̻߳á°ïÖúËüÍê³ÉʣϵÄÈÎÎñ¡£Òò´Ë£¬Ìá¸ßÁËÏ̵߳ÄÀûÓÃÂÊ£¬´Ó¶øÌá¸ßÁËÕûÌåÐÔÄÜ¡£
ÕâÁ½ÖÖÏ̳߳ضÔÓÚÈÎÎñ¹¤×÷Á¿²»¾ùºâʱµÄÖ´ÐÐʱ¼ä£º

×¢Òâµ½µ±Ïß³ÌÊýÁ¿Îª1ʱ£¬Á½ÕßµÄÖ´ÐÐʱ¼ä²îÒì²¢²»Ã÷ÏÔ¡£ÕâÊÇÒòΪ×ܵļÆËãÁ¿ÊÇÏàͬµÄ£¬¶øForkJoinPoolÂýµÄÄÇÒ»Ãë¶àÊÇÒòΪËü´´½¨Á˷dz£¶àµÄÈÎÎñ£¬Í¬Ê±Ò²µ¼ÖÂÁËGCµÄ¹¤×÷Á¿Ôö¼Ó¡£
µ±Ïß³ÌÊýÁ¿Ôö¼Óµ½4ʱ£¬Ö´ÐÐʱ¼äµÄÇø±ð¾Í½Ï´óÁË£¬ForkJoinPoolµÄÐÔÄܱÈThreadPoolExecutorºÃ½«½ü50%£¬¿É¼ûWork
StealingÔÚÓ¦¶ÔÈÎÎñÁ¿²»¾ùºâµÄÇé¿öÏ£¬Äܹ»±£Ö¤×ÊÔ´µÄÀûÓÃÂÊ¡£
ËùÒÔÒ»¸ö½áÂÛ¾ÍÊÇ£ºµ±ÈÎÎñµÄÈÎÎñÁ¿¾ùºâʱ£¬Ñ¡ÔñThreadPoolExecutorÍùÍù¸üºÃ£¬·´Ö®ÔòÑ¡ÔñForkJoinPool¡£
ÁíÍ⣬¶ÔÓÚForkJoinPool£¬»¹ÓÐÒ»¸öÒòËØ»áÓ°ÏìËüµÄÐÔÄÜ£¬¾ÍÊÇÍ£Ö¹½øÐÐÈÎÎñ·Ö¸îµÄÄǸöãÐÖµ¡£±ÈÈçÔÚ֮ǰµÄ¿ìËÙÅÅÐòÖУ¬µ±Ê£ÏµÄÔªËØÊýÁ¿Ð¡ÓÚ10µÄʱºò£¬¾Í»áÍ£Ö¹×ÓÈÎÎñµÄ´´½¨¡£Ï±íÏÔʾÁËÔÚ²»Í¬ãÐֵϣ¬ForkJoinPoolµÄÐÔÄÜ£º

¿ÉÒÔ·¢ÏÖ£¬µ±ãÐÖµ²»Í¬Ê±£¬¶ÔÓÚÐÔÄÜÒ²»áÓÐÒ»¶¨Ó°Ïì¡£Òò´Ë£¬ÔÚʹÓÃForkJoinPoolʱ£¬¶Ô´ËãÐÖµ½øÐвâÊÔ£¬Ê¹ÓÃÒ»¸ö×îºÏÊʵÄÖµÒ²ÓÐÖúÓÚÕûÌåÐÔÄÜ¡£
×Ô¶¯²¢Ðл¯(Automatic Parallelization)
ÔÚJava 8ÖУ¬ÒýÈëÁË×Ô¶¯²¢Ðл¯µÄ¸ÅÄî¡£ËüÄܹ»ÈÃÒ»²¿·ÖJava´úÂë×Ô¶¯µØÒÔ²¢Ðеķ½Ê½Ö´ÐУ¬Ç°ÌáÊÇʹÓÃÁËForkJoinPool¡£
Java 8ΪForkJoinPoolÌí¼ÓÁËÒ»¸öͨÓÃÏ̳߳أ¬Õâ¸öÏ̳߳ØÓÃÀ´´¦ÀíÄÇЩûÓб»ÏÔʽÌá½»µ½ÈκÎÏ̳߳صÄÈÎÎñ¡£ËüÊÇForkJoinPoolÀàÐÍÉϵÄÒ»¸ö¾²Ì¬ÔªËØ£¬ËüÓµÓеÄĬÈÏÏß³ÌÊýÁ¿µÈÓÚÔËÐмÆËã»úÉϵĴ¦ÀíÆ÷ÊýÁ¿¡£
µ±µ÷ÓÃArraysÀàÉÏÌí¼ÓµÄз½·¨Ê±£¬×Ô¶¯²¢Ðл¯¾Í»á·¢Éú¡£±ÈÈçÓÃÀ´ÅÅÐòÒ»¸öÊý×éµÄ²¢ÐпìËÙÅÅÐò£¬ÓÃÀ´¶ÔÒ»¸öÊý×éÖеÄÔªËØ½øÐв¢ÐбéÀú¡£×Ô¶¯²¢Ðл¯Ò²±»ÔËÓÃÔÚJava
8ÐÂÌí¼ÓµÄStream APIÖС£
±ÈÈçÏÂÃæµÄ´úÂëÓÃÀ´±éÀúÁбíÖеÄÔªËØ²¢Ö´ÐÐÐèÒªµÄ¼ÆË㣺
Stream<Integer> stream = arrayList.parallelStream(); stream.forEach(a -> { String symbol = StockPriceUtils.makeSymbol(a); StockPriceHistory sph = new StockPriceHistoryImpl(symbol, startDate, endDate, entityManager); }); |
¶ÔÓÚÁбíÖеÄÔªËØµÄ¼ÆËã¶¼»áÒÔ²¢Ðеķ½Ê½Ö´ÐС£forEach·½·¨»áΪÿ¸öÔªËØµÄ¼ÆËã²Ù×÷´´½¨Ò»¸öÈÎÎñ£¬¸ÃÈÎÎñ»á±»Ç°ÎÄÖÐÌáµ½µÄForkJoinPoolÖеÄͨÓÃÏ̳߳ش¦Àí¡£ÒÔÉϵIJ¢ÐмÆËãÂß¼µ±È»Ò²¿ÉÒÔʹÓÃThreadPoolExecutorÍê³É£¬µ«ÊǾʹúÂëµÄ¿É¶ÁÐԺʹúÂëÁ¿¶øÑÔ£¬Ê¹ÓÃForkJoinPoolÃ÷ÏÔ¸üʤһ³ï¡£
¶ÔÓÚForkJoinPoolͨÓÃÏ̳߳صÄÏß³ÌÊýÁ¿£¬Í¨³£Ê¹ÓÃĬÈÏÖµ¾Í¿ÉÒÔÁË£¬¼´ÔËÐÐʱ¼ÆËã»úµÄ´¦ÀíÆ÷ÊýÁ¿¡£Èç¹ûÐèÒªµ÷ÕûÏß³ÌÊýÁ¿£¬¿ÉÒÔͨ¹ýÉèÖÃϵͳÊôÐÔ£º-Djava.util.concurrent.ForkJoinPool.common.parallelism=N
ÏÂÃæµÄÒ»×éÊý¾ÝÓÃÀ´±È½ÏʹÓÃThreadPoolExecutorºÍForkJoinPoolÖеÄͨÓÃÏ̳߳ØÀ´Íê³ÉÉÏÃæ¼òµ¥¼ÆËãʱµÄÐÔÄÜ£º

×¢Òâµ½µ±Ïß³ÌÊýΪ1£¬2£¬4ʱ£¬ÐÔÄܲîÒìµÄ±È½ÏÃ÷ÏÔ¡£Ïß³ÌÊýΪ1µÄForkJoinPoolͨÓÃÏ̳߳غÍÏß³ÌÊýΪ2µÄThreadPoolExecutorµÄÐÔÄÜÊ®·Ö½Ó½ü¡£
³öÏÖÕâÖÖÏÖÏóµÄÔÒòÊÇ£¬forEach·½·¨ÓÃÁËһЩС°ÑÏ·¡£Ëü»á½«Ö´ÐÐforEach±¾ÉíµÄÏß³ÌÒ²×÷ΪÏ̳߳ØÖеÄÒ»¸ö¹¤×÷Ï̡߳£Òò´Ë£¬¼´Ê¹½«ForkJoinPoolµÄͨÓÃÏ̳߳صÄÏß³ÌÊýÁ¿ÉèÖÃΪ1£¬Êµ¼ÊÉÏÒ²»áÓÐ2¸ö¹¤×÷Ï̡߳£Òò´ËÔÚʹÓÃforEachµÄʱºò£¬Ïß³ÌÊýΪ1µÄForkJoinPoolͨÓÃÏ̳߳غÍÏß³ÌÊýΪ2µÄThreadPoolExecutorÊǵȼ۵ġ£
ËùÒÔµ±ForkJoinPoolͨÓÃÏ̳߳ØÊµ¼ÊÐèÒª4¸ö¹¤×÷Ïß³Ìʱ£¬¿ÉÒÔ½«ËüÉèÖóÉ3£¬ÄÇôÔÚÔËÐÐʱ¿ÉÓõŤ×÷Ï߳̾ÍÊÇ4ÁË¡£
×ܽá
1.µ±ÐèÒª´¦ÀíµÝ¹é·ÖÖÎË㷨ʱ£¬¿¼ÂÇʹÓÃForkJoinPool¡£
2.×ÐϸÉèÖò»ÔÙ½øÐÐÈÎÎñ»®·ÖµÄãÐÖµ£¬Õâ¸öãÐÖµ¶ÔÐÔÄÜÓÐÓ°Ïì¡£
3.Java 8ÖеÄÒ»Ð©ÌØÐÔ»áʹÓõ½ForkJoinPoolÖеÄͨÓÃÏ̳߳ء£ÔÚijЩ³¡ºÏÏ£¬ÐèÒªµ÷Õû¸ÃÏ̳߳صÄĬÈϵÄÏß³ÌÊýÁ¿¡£
|