Chapter 2-3. Fork/Join Framework

ไฝ•่ฌ‚fork/Join

Fork/Joinๆ˜ฏๅพžJDK7้–‹ๅง‹ๆไพ›็š„ไธ€ๅ€‹็”จๆ–ผๅนณ่กŒๅŸท่กŒไปปๅ‹™็š„ๆก†ๆžถ, ๆ˜ฏไธ€ๅ€‹ๅฏไปฅๆŠŠๆฏไปปๅ‹™ๅˆ‡ๅ‰ฒๆˆๅคšๅ€‹ๅญไปปๅ‹™, ไธฆไธ”ๆœ€็ต‚ๅฝ™ๆ•ดๅ„ๅ€‹ๅญไปปๅ‹™็š„็ตๆžœไธฆๅพ—ๅˆฐๆฏไปปๅ‹™ไน‹็ตๆžœ็š„ๆก†ๆžถ.

  • Fork: ๅณๆŠŠไธ€ๅ€‹ๆฏไปปๅ‹™ๅˆ‡ๅ‰ฒๆˆๅคšๅ€‹ๅญไปปๅ‹™ไธฆไธ”ๅนณ่กŒๅœฐๅŸท่กŒ.

  • Join: ๅˆไฝตๅˆ‡ๅ‰ฒๅพŒ็š„ๅญไปปๅ‹™ไน‹ๅŸท่กŒ็ตๆžœ, ๆœ€็ต‚ๅพ—ๅˆฐๆฏไปปๅ‹™ไน‹็ตๆžœ.

ไพ‹ๅฆ‚: ่จˆ็ฎ—ๆ•ดๆ•ธ1~10000็š„ๅŠ ็ธฝ, ๅฏไปฅๅˆ‡ๅ‰ฒๆˆ100ๅ€‹ๅญไปปๅ‹™, ๆฏๅ€‹ๅญไปปๅ‹™ๅˆ†ๅˆฅๅฐ100ๅ€‹ๆ•ดๆ•ธ้€ฒ่กŒๅŠ ็ธฝ, ๆœ€็ต‚ๅฝ™ๆ•ด้€™100ๅ€‹ๅญไปปๅ‹™็š„็ตๆžœ.

Fork/Join็š„้‹ไฝœๆต็จ‹ๅœ–ๅฆ‚ไธ‹:

Work-Stealingๆผ”็ฎ—ๆณ•

Work-stealingๆผ”็ฎ—ๆณ•ๆ˜ฏๆŒ‡ๆŸๅ€‹ๅŸท่กŒ็ท’ๅพžๅ…ถๅฎƒqueue่ฃก"็ซŠๅ–(steal)"ไปปๅ‹™ไพ†ๅŸท่กŒ, ๅ…ถ้‹ไฝœๆต็จ‹ๅœ–ๅฆ‚ไธ‹:

่‡ณๆ–ผ็‚บไฝ•่ฆๆœ‰้€™็จฎๆผ”็ฎ—ๆณ•ๅ‘ข? ๅ‡่จญ็•ถๅ‰ๆœ‰ไธ€ๅ€‹ๆฏ”่ผƒๅคง็š„ๆฏไปปๅ‹™, ๆˆ‘ๅ€‘ๅฏไปฅๆŠŠ้€™ๅ€‹ๆฏไปปๅ‹™ๅˆ‡ๅ‰ฒ็‚บ่‹ฅๅนฒๅ€‹ไบ’ไธ็›ธไพ็š„ๅญไปปๅ‹™, ็„ถ่€Œ็‚บไบ†ๆธ›ๅฐ‘ๅŸท่กŒ็ท’ไน‹้–“็š„็ซถ็ˆญ, ไพฟๆŠŠ้€™ไบ›ๅญไปปๅ‹™ๅˆ†ๅˆฅๆ”พๅˆฐไธๅŒ็š„queue่ฃก, ไธฆ็‚บๆฏๅ€‹queueๅปบ็ซ‹ไธ€ๅ€‹ๅ–ฎ็จ็š„ๅŸท่กŒ็ท’ไพ†ๅŸท่กŒqueue่ฃก็š„ไปปๅ‹™, ๅŸท่กŒ็ท’่ˆ‡queueไธ€ไธ€ๅฐๆ‡‰, ๅณAๅŸท่กŒ็ท’่ฒ ่ฒฌ่™•็†queue A่ฃก็š„ไปปๅ‹™, ไฝ†ๆ˜ฏๆœ‰็š„ๅŸท่กŒ็ท’ๅฏ่ƒฝๆœƒๅ…ˆๆŠŠ่‡ชๅทฑ็š„queueไธญ็š„ไปปๅ‹™ๅฎŒๆˆ, ่€Œๅ…ถๅฎƒๅŸท่กŒ็ท’ๅฐๆ‡‰็š„queue่ฃกๅป้‚„ๆœ‰ไปปๅ‹™ๅœจ็ญ‰ๅพ…่™•็†ไธญ. ๆ‰€ไปฅ, ๅทฒ็ถ“ๅฎŒๆˆๆ‰€ๆœ‰ไปปๅ‹™็š„ๅŸท่กŒ็ท’่ˆ‡ๅ…ถๅœจ้‚ฃ้‚Šไนพ็ญ‰, ๅ€’ไธๅฆ‚ๅŽปๅนซๅ…ถๅฎƒๅŸท่กŒ็ท’ๅฎŒๆˆๅ‰ฉไธ‹็š„ไปปๅ‹™, ๆ–ผๆ˜ฏ้€™ๅ€‹ๅทฒ็ถ“ๆฒ’ไบ‹ๅš็š„ๅŸท่กŒ็ท’ๅฐฑๆœƒๅŽปๅ…ถๅฎƒ็š„queue่ฃก็ซŠๅ–ไธ€ๅ€‹ไปปๅ‹™ไพ†ๅŸท่กŒ. ๅœจ้€™็จฎๆƒ…ๆณไธ‹, ๅฎƒๅ€‘ๆœƒๅญ˜ๅ–ๅŒไธ€ๅ€‹queue, ๆ‰€ไปฅ็‚บไบ†ๆธ›ๅฐ‘็ซŠๅ–ไปปๅ‹™็š„ๅŸท่กŒ็ท’่ˆ‡่ขซ็ซŠๅ–ไปปๅ‹™็š„ๅŸท่กŒ็ท’ไน‹้–“็š„็ซถ็ˆญ, ้€šๅธธๆœƒไฝฟ็”จ้›™ๅ‘ไฝ‡ๅˆ—(double-ended queue, a.k.a Deque, ๅ…ถ็™ผ้Ÿณ็‚บ"deck") --- ่ขซ็ซŠๅ–ไปปๅ‹™็š„ๅŸท่กŒ็ท’ๆฐธ้ ๅพž้›™ๅ‘ไฝ‡ๅˆ—็š„้ ญ้ƒจๅ–ๅ‡บไปปๅ‹™ไพ†ๅŸท่กŒ, ่€Œ็ซŠๅ–ไปปๅ‹™็š„ๅŸท่กŒ็ท’ๆฐธ้ ๅพž้›™ๅ‘ไฝ‡ๅˆ—็š„ๅฐพ้ƒจๅ–ๅ‡บไปปๅ‹™ไพ†ๅŸท่กŒ.

Work-stealing็š„ๅ„ช้ปž: ๅ……ๅˆ†ๅœฐๅˆฉ็”จๅŸท่กŒ็ท’้€ฒ่กŒๅนณ่กŒ้‹็ฎ—.

Work-stealing็š„็ผบ้ปž: ๅœจๆŸไบ›ๆƒ…ๆณไธ‹้‚„ๆ˜ฏๅญ˜ๅœจ็ซถ็ˆญ, ่ญฌๅฆ‚้›™ๅ‘ไฝ‡ๅˆ—่ฃกๅชๆœ‰ไธ€ๅ€‹ไปปๅ‹™ๆ™‚. ้™คไบ†้€™้ปžไน‹ๅค–, ๅฆไธ€ๅ€‹็ผบ้ปžๆ˜ฏๅ…ถๆถˆ่€—ไบ†ๆ›ดๅคš็š„็ณป็ตฑ่ณ‡ๆบ, ่ญฌๅฆ‚ๅปบ็ซ‹ไบ†ๅคšๅ€‹ๅŸท่กŒ็ท’ไปฅๅŠ้›™ๅ‘ไฝ‡ๅˆ—.

Fork/Join็š„ๅŸบๆœฌไป‹็ดน

ๅ‰้ข็š„้ƒจๅˆ†ๅทฒ็ถ“ๆธ…ๆฅšๅœฐ่ชชๆ˜Žไบ†Fork/Joinๆก†ๆžถ็š„้œ€ๆฑ‚ไบ†, ๅ†ไพ†ๅฐฑๅฏไปฅๆ€่€ƒไธ€ไธ‹่‹ฅ่ฆ่จญ่จˆไธ€ๅ€‹Fork/Joinๆก†ๆžถ็š„่ฉฑ่ฉฒ่ฆๅฆ‚ไฝ•่จญ่จˆ.

็ฌฌไธ€ๆญฅ, ๅˆ†ๅ‰ฒไปปๅ‹™: ้ฆ–ๅ…ˆ้œ€่ฆๆœ‰ไธ€ๅ€‹fork้กžๅˆฅไพ†ๆŠŠๆฏไปปๅ‹™ๅˆ†ๅ‰ฒๆˆๅญไปปๅ‹™, ่‹ฅๅˆ†ๅ‰ฒๅพŒ็š„ๅญไปปๅ‹™้‚„ๆ˜ฏๅคชๅคง, ๅฐฑ็นผ็บŒๅˆ†ๅ‰ฒ, ็›ดๅˆฐๅญไปปๅ‹™ๅค ๅฐ็‚บๆญข.

็ฌฌไบŒ้ƒจ, ๅŸท่กŒไปปๅ‹™ไธฆๅˆไฝต็ตๆžœ: ๅˆ†ๅ‰ฒ็š„ๅญไปปๅ‹™ๅˆ†ๅˆฅๆ”พๅœจ้›™ๅ‘ไฝ‡ๅˆ—ไธญ, ็„ถๅพŒๅนพๅ€‹ๅ•Ÿๅ‹•็š„ๅŸท่กŒ็ท’ๅˆ†ๅˆฅๅพž้›™ๅ‘ไฝ‡ๅˆ—่ฃกๅ–ๅพ—ไปปๅ‹™ไธฆๅŸท่กŒ. ๅญไปปๅ‹™ๅŸท่กŒๅฎŒ็š„็ตๆžœ้ƒฝ็ตฑไธ€ๆ”พๅœจไธ€ๅ€‹ไฝ‡ๅˆ—่ฃก, ๅ•Ÿๅ‹•ไธ€ๅ€‹ๅŸท่กŒ็ท’ๅพž้€™ๅ€‹ไฝ‡ๅˆ—่ฃกๆ‹ฟ่ณ‡ๆ–™, ไธฆไธ”ๅˆไฝต้€™ไบ›่ณ‡ๆ–™.

Fork/Joinไฝฟ็”จๅ…ฉๅ€‹้กžๅˆฅไพ†ๅฎŒๆˆไธŠ่ฟฐ็š„ๅ…ฉไปถไบ‹ๆƒ…:

  • ForkJoinTask: ่ฆไฝฟ็”จFork/Joinๆก†ๆžถ, ๅฟ…้ ˆๅ…ˆๅปบ็ซ‹ไธ€ๅ€‹ForkJoinไปปๅ‹™. ๅ…ถๆไพ›ๅœจไปปๅ‹™ไธญๅŸท่กŒfork()่ˆ‡join()ๆ“ไฝœไน‹ๆฉŸๅˆถ, ้€šๅธธๆƒ…ๆณไธ‹ๆˆ‘ๅ€‘ไธ้œ€่ฆ็›ดๆŽฅ็นผๆ‰ฟForkJoinTask้กžๅˆฅ, ่€Œๅช้œ€่ฆ็นผๆ‰ฟๅ…ถๅญ้กžๅˆฅ, ๅฆ‚ไธ‹:

    • RecursiveAction: ็”จๆ–ผๆฒ’ๆœ‰ๅ›žๅ‚ณๅ€ผ็š„ไปปๅ‹™.

    • RecursiveTask: ็”จๆ–ผๆœ‰ๅ›žๅ‚ณๅ€ผ็š„ไปปๅ‹™.

  • ForkJoinPool: ForkJoinTask้œ€่ฆ้€š้ŽForkJoinPoolไพ†ๅŸท่กŒ, ไปปๅ‹™ๅˆ†ๅ‰ฒๅ‡บ็š„ๅญไปปๅ‹™ๆœƒๆทปๅŠ ๅˆฐ็•ถๅ‰ๅทฅไฝœๅŸท่กŒ็ท’ๆ‰€็ถญ่ญท็š„้›™ๅ‘ไฝ‡ๅˆ—ไธญ, ้€ฒๅ…ฅไฝ‡ๅˆ—็š„้ ญ้ƒจ. ็•ถไธ€ๅ€‹ๅทฅไฝœๅŸท่กŒ็ท’็š„ไฝ‡ๅˆ—ไธญๆšซๆ™‚ๆฒ’ๆœ‰ไปปๅ‹™ๆ™‚, ๅ…ถๆœƒ้šจๆฉŸๅœฐๅพžๅ…ถๅฎƒๅทฅไฝœๅŸท่กŒ็ท’็š„ไฝ‡ๅˆ—ไน‹ๅฐพ้ƒจ็ฒๅ–ไธ€ๅ€‹ไปปๅ‹™.

ไฝฟ็”จFork/Join

้€™้‚Šๅฐฑ็”จไธ€ๅ€‹็ฐกๅ–ฎ็š„็ฏ„ไพ‹ไพ†็คบ็ฏ„ๆ€Ž้บผไฝฟ็”จFork/Join, ้œ€ๆฑ‚็‚บ: ่จˆ็ฎ—1+2+3+4+....+100็š„็ตๆžœ.

ไฝฟ็”จFork/Joinๆก†ๆžถ้ฆ–ๅ…ˆ่ฆ่€ƒๆ…ฎๅˆฐ็š„ๆ˜ฏๅฆ‚ไฝ•ๅˆ†ๅ‰ฒไปปๅ‹™, ่‹ฅๆˆ‘ๅ€‘ๅธŒๆœ›ๆฏๅ€‹ๅญไปปๅ‹™ๆœ€ๅคšๅŸท่กŒๅ››ๅ€‹ๆ•ธๅญ—็š„็›ธๅŠ , ้‚ฃ้บผๆˆ‘ๅ€‘ๅฏไปฅ่จญ็ฝฎthreshold็‚บ4, ็”ฑๆ–ผๆ˜ฏ100ๅ€‹ๆ•ธๅญ—็›ธๅŠ , ๆ‰€ไปฅFork/Joinๆก†ๆžถๆœƒๆŠŠ้€™ๅ€‹ไปปๅ‹™forkๆˆ25ๅ€‹ๅญไปปๅ‹™, ๅญไปปๅ‹™ไธ€่ฒ ่ฒฌ่จˆ็ฎ—1+2+3+4, ๅญไปปๅ‹™ไบŒ่ฒ ่ฒฌ5+6+7+8 ..., ไปฅๆญค้กžๆŽจ, ๆœ€ๅพŒๅ†joinๆ‰€ๆœ‰ๅญไปปๅ‹™็š„็ตๆžœ.

ๅ› ็‚บ้€™ๆ˜ฏๅ€‹ๆœ‰็ตๆžœ(ๅ›žๅ‚ณๅ€ผ)็š„ไปปๅ‹™, ๆ‰€ไปฅๅฟ…้ ˆ็นผๆ‰ฟRecursiveTask, ๅฏฆไฝœๅ…งๅฎนๅฆ‚ไธ‹:

ๅŸท่กŒ็ตๆžœ:

็ฏ„ไพ‹็จ‹ๅผ็ขผcommit็ด€้Œ„้ปžๆˆ‘arrow-up-right.

้€š้Ž้€™ๅ€‹็ฏ„ไพ‹ๆˆ‘ๅ€‘ๅฏไปฅๅ†็œ‹ๆ›ดๆทฑไธ€้ปž, ้—œๆ–ผForkJoinTask, ๅ…ถ่ˆ‡ไธ€่ˆฌไปปๅ‹™ไน‹ไธป่ฆๅ€ๅˆฅๅœจๆ–ผๅ…ถ้œ€่ฆๅฏฆไฝœcomputeๆ–นๆณ•, ๅœจ้€™ๅ€‹ๆ–นๆณ•ไธญ, ้ฆ–ๅ…ˆ้œ€่ฆๅˆคๆ–ทไปปๅ‹™ๆ˜ฏๅฆ่ถณๅค ๅฐ, ่‹ฅๅค ๅฐๅฐฑ็›ดๆŽฅๅŸท่กŒไปปๅ‹™; ๅไน‹ๅฐฑๅฟ…้ ˆ้€ฒ่กŒไปปๅ‹™ๅˆ†ๅ‰ฒ. ๆฏๅ€‹ๅญไปปๅ‹™ๅœจๅ‘ผๅซforkๆ–นๆณ•ๆ™‚, ๅˆๆœƒ้€ฒๅ…ฅcomputeๆ–นๆณ•, ็œ‹็œ‹็•ถๅ‰็š„ๅญไปปๅ‹™ๆ˜ฏๅฆ้œ€่ฆ็นผ็บŒๅพ€ไธ‹ๅˆ†ๅ‰ฒๆˆๆ›ดๅคš็š„ๅญไปปๅ‹™, ่‹ฅไธ้œ€่ฆ, ๅฐฑๅŸท่กŒ็•ถๅ‰ๅญไปปๅ‹™ไธฆไธ”ๅ›žๅ‚ณ็ตๆžœ. ไฝฟ็”จjoinๆ–นๆณ•ๅ‰‡ๆœƒ็ญ‰ๅพ…ๅญไปปๅ‹™ๅŸท่กŒๅฎŒๆˆไธฆไธ”ๅพ—ๅˆฐๅ…ถ็ตๆžœ.

Fork/Joinไธญ็š„Exception Handling

ForkJoinTaskๅœจๅŸท่กŒ็š„ๆ™‚ๅ€™ๅฏ่ƒฝๆœƒๆ‹‹ๅ‡บexception, ไฝ†ๆ˜ฏๆˆ‘ๅ€‘ๆฒ’่พฆๆณ•ๆ–ผmain threadไธญ็›ดๆŽฅcatch้€™ไบ›exception, ๆ•…ForkJoinTaskๆไพ›ไบ†isCompletedAbnormally()ๆ–นๆณ•ไพ†ๆชขๆŸฅไปปๅ‹™ๆ˜ฏๅฆๅทฒ็ถ“ๆ‹‹ๅ‡บexceptionๆˆ–ๆ˜ฏๅทฒ็ถ“่ขซๅ–ๆถˆไบ†, ไธฆไธ”ๅฏไปฅ้€š้ŽForkJoinTask็š„getException()ๆ–นๆณ•ๅ–ๅพ—exception. ไฝฟ็”จไธŠๅคงๆฆ‚้•ทๅพ—ๅƒ้€™ๆจฃ(ๆ“ทๅ–่‡ชๅ‰้ข็š„็ฏ„ไพ‹็จ‹ๅผ็ขผ): getException()ๅ›žๅ‚ณThrowable็‰ฉไปถ, ่‹ฅไปปๅ‹™่ขซๅ–ๆถˆไบ†ๅ‰‡ๅ›žๅ‚ณCancellationException. ่‹ฅไปปๅ‹™ๆฒ’ๆœ‰ๅฎŒๆˆ่‹ฅ่‘—ๆฒ’ๆœ‰ๆ‹‹ๅ‡บexceptionๅ‰‡ๅ›žๅ‚ณnull.

Fork/Join็š„ๅฏฆไฝœๅŽŸ็†

ForkJoinPool็”ฑForkJoinTask้™ฃๅˆ—่ˆ‡ForkJoinWorkerThread้™ฃๅˆ—็ต„ๆˆ, ForkJoinTask้™ฃๅˆ—่ฒ ่ฒฌๅญ˜ๆ”พ็จ‹ๅผๆไบค็ตฆForkJoinPool็š„ไปป็‰ฉ, ่€ŒForkJoinWorkerThread้™ฃๅˆ—ๅ‰‡่ฒ ่ฒฌๅŸท่กŒ้€™ไบ›ไปปๅ‹™.

1. ForkJoinTask็š„forkๆ–นๆณ•ๅฏฆไฝœๅŽŸ็†:

็•ถๆˆ‘ๅ€‘ๅ‘ผๅซForkJoinTask็š„forkๆ–นๆณ•ๆ™‚, ็จ‹ๅผๆœƒๅ‘ผๅซForkJoinWorkerThread็š„workQueue(ForkJoinPool.WorkQueue)็š„pushๆ–นๆณ•้žๅŒๆญฅๅœฐๅŸท่กŒ้€™ๅ€‹ไปปๅ‹™, ็„ถๅพŒ็ซ‹ๅˆปๅ›žๅ‚ณ็ตๆžœ, ๅŽŸๅง‹็ขผๅฆ‚ไธ‹:

็ฌฌ700่กŒ็š„pushๆ–นๆณ•ๆŠŠ็•ถๅ‰็š„ไปปๅ‹™ๅญ˜ๆ”พๅœจForkJoinTask้™ฃๅˆ—queue่ฃก, ็„ถๅพŒๅ†ๅ‘ผๅซForkJoinPool็š„signalWorkๆ–นๆณ•ๅ–š้†’(active)ๆˆ–ๅ‰ต้€ ไธ€ๅ€‹ๅทฅไฝœๅŸท่กŒ็ท’ไพ†ๅŸท่กŒไปปๅ‹™, ๅŽŸๅง‹็ขผๅฆ‚ไธ‹:

2. ForkJoinTask็š„joinๆ–นๆณ•ๅฏฆไฝœๅŽŸ็†:

joinๆ–นๆณ•็š„ไธป่ฆไฝœ็”จๆ˜ฏ้˜ปๅกž(block)็•ถๅ‰ๅŸท่กŒ็ท’ไธฆไธ”็ญ‰ๅพ…็ฒๅพ—็ตๆžœ, ๅ…ถๅŽŸๅง‹็ขผๅฆ‚ไธ‹:

้ฆ–ๅ…ˆ, ๅ…ถๅ‘ผๅซไบ†doJoin(), ้€š้ŽdoJoin()ๅพ—ๅˆฐ็•ถๅ‰ไปปๅ‹™็š„็‹€ๆ…‹ไพ†ๅˆคๆ–ทๅ›žๅ‚ณไป€้บผ็ตๆžœ, ไปปๅ‹™็‹€ๆ…‹ๆœ‰ๅ››็จฎ: NORMAL(ๅทฒๅฎŒๆˆ), CANCELLED(่ขซๅ–ๆถˆ), SIGNAL(ไฟก่™Ÿ)ไปฅๅŠEXCEPTIONAL(ๅ‡บ็พ็•ฐๅธธ), ๅฆ‚ไธ‹ๅœ–(้€™้‚ŠไธๆŠŠMASK็•ถ็‹€ๆ…‹ไพ†็œ‹ๅพ…):

  • ่‹ฅไปปๅ‹™็‹€ๆ…‹ๆ˜ฏNORMAL, ๅ‰‡็›ดๆŽฅๅ›žๅ‚ณไปปๅ‹™็ตๆžœ.

  • ่‹ฅไปปๅ‹™็‹€ๆ…‹ๆ˜ฏCANCELLED, ๅ‰‡็›ดๆŽฅๆ‹‹ๅ‡บCancellationException.

  • ่‹ฅไปปๅ‹™็‹€ๆ…‹ๆ˜ฏEXCEPTIONAL, ๅ‰‡็›ดๆŽฅๆ‹‹ๅ‡บๅฐๆ‡‰็š„็•ฐๅธธ.

ๆ‹‹ๅ‡บ็•ฐๅธธ็š„้ƒจไปฝ(reportException)ๅฆ‚ไธ‹ๅœ–:

ๅ†ไพ†, ็œ‹ไธ€ไธ‹doJoin็š„ๅŽŸๅง‹็ขผ:

ๅœจdoJoinไธญ, ้ฆ–ๅ…ˆ้€š้ŽๆŸฅ็œ‹ไปปๅ‹™็š„็‹€ๆ…‹, ็œ‹ๆ˜ฏๅฆๅทฒ็ถ“ๅŸท่กŒๅฎŒไบ†(s < 0, negative means NORMAL), ่‹ฅๅŸท่กŒๅฎŒ็•ข, ๅ‰‡็›ดๆŽฅๅ›žๅ‚ณไปปๅ‹™็‹€ๆ…‹; ๅไน‹, ๅ‰‡ๅพžไปปๅ‹™้™ฃๅˆ—่ฃกๅ–ๅ‡บไปปๅ‹™ไธฆไธ”้€้ŽdoExec()ๅŸท่กŒไปปๅ‹™, ๅ…ถไธญ็š„exec()ๆœƒ็”ฑ็นผๆ‰ฟForkJoinTask็š„้กžๅˆฅๅฏฆไฝœ(ๆญค่™•็”ฑRecursiveTaskๅฏฆไฝœ). ่‹ฅไปปๅ‹™้ †ๅˆฉๅŸท่กŒๅฎŒไบ†, ๅ‰‡ๆŠŠไปปๅ‹™็‹€ๆ…‹่จญๅฎš็‚บNORMAL; ๅไน‹ๅ‰‡็ด€้Œ„exception, ไธฆๆŠŠไปปๅ‹™็‹€ๆ…‹่จญ็‚บEXCEPTIONAL, doExec()ๅŽŸๅง‹็ขผๅฆ‚ไธ‹:

ๆœ€ๅพŒ, joinไธญ็š„getRawResultๆ–นๆณ•ๅ‰‡ๆœƒไบค็”ฑ็นผๆ‰ฟForkJoinTask็š„้กžๅˆฅๅฏฆไฝœ(ๆญค่™•็‚บRecursiveTask), ็œ‹่ตทไพ†ๅฐฑๅชๆ˜ฏๆŠŠ่จˆ็ฎ—ๅฎŒ็š„็ตๆžœๅ‚ณๅ›žๅŽป่€Œๅทฒ:

ๅƒ่€ƒ่ณ‡ๆ–™

  • JDKๅŽŸๅง‹็ขผ(1.8.0_152)

Last updated