What is the difference between the old ExecutorService of 1.5 and the new ForkJoinPool of 1.7? What can I do with ForkJoinPool , what can't I do with the old ExecutorService options? Or what is easier to do with ForkJoinPool ?
- 2The question is initially incorrect, since one is the interface, the other is the implementation. - etki
- oneWell, according to the classic javadoc, in which there is a whole section that starts with the words A ForkJoinPool differs docs.oracle.com/javase/8/docs/api/java/util/concurrent/… - etki
- @etki in question is not about classes and implementations, but about frameworks as a whole. How about packages solving a range of problems. There was a 1.5 ExecutorService and lived with him, and then they made ForkJoin, which means that he relieves some kind of pain, unlike the one that’s causing this. - Pavel
- oneAnd now they still live with him. Because this is the interface, and ForkJoinPool is its implementation. - etki
- @etki I understand that I mean that this implementation is new compared to the options from 1.5 - Pavel
2 answers
As far as I understand the difference here is as follows:
ExecutorServicehas a common queue of tasks and a number of threads, which take turns in tasks and execute them.ForkJoinPoolhas a certain number of threads, but it still has a queue of tasks for each thread. The flow in the course of work can split up the task into several tasks, one it adds to itself in the queue and the other executes, and this can be repeated recursively. If another thread has emptied its turn, then it can take tasks from another thread, from the end of the queue. The described mechanism is called work-stealing . This is the key to distinguishing thread-pool data.
It is recommended to use ForkJoinPool , if you have a set of tasks that recursively repeat. This allows full use of work-stealing . If the tasks are not broken in the process of work, then you will not get any benefits, although you will not find any disadvantages from using them either.
More information
The classic ExecutorService implementations created separate threads and owned them. ForkJoinPool does not create separate threads, but uses existing ones while they are “sleeping” on join-like calls, which is its strengths and weaknesses.
Classic ExecutorService usually cannot be used with tasks that synchronously wait for each other - they quickly exhaust the available pool of threads, which leads either to a deadlock or to its unlimited swelling. ForkJoinPool is able to resolve such situations.
On the other hand, tasks performed as part of the ForkJoinPool must be fairly short.
PS personally it seems to me that any use of the ForkJoinPool is a crutch to bypass the problem of weak architecture
- Mayorov ExecutorService usually cannot be used with tasks that synchronously wait for each other, but how can barriers really not solve this problem? - Pavel
- one@ Pavel? What are the barriers? I’m talking about a situation where a task calls the
.get()method from another, that from the third, and the third waits for the fourth. If there are only 3 threads in the pool, there will be a deadlock. - Pavel Mayorov