ExecuterService is an interface, and the ForkJoinPool is one implementation of it. This pool will look for the available CPU and create that many worker threads. The load is then distributed evenly across each thread.
The tasks aredistributed to each thread using a thread-specific deque. The following diagram shows each thread having its own buffer of tasks. The buffer is a deque—a data structure that allows pushing and popping from either end of the buffer:

The deque allows threads to employ work stealing. It could happen that some tasks are computation heavy, and, as a result, the processing threads might take longer. On the other hand, other pool threads might get lighter tasks and won't have any work left to do.
The free threads could steal the task from the deque of some overloaded, random thread. This design makes for the efficient handling of tasks. The following code shows how the pool thread works. The thread is represented by the,TaskStealingThread
class: ...