It otherwise enters a synchronized lock to check if the DEQ is actually empty, if so failing. They pre-increment base , and then check against top . A push operation can normally run concurrently with a steal. The put operation always requires synchronization. When a FJTaskRunner thread has no tasks of its own to run, it tries to be a good citizen.
Threads run at lower priority while scanning for work.
This is well-behaved so long as the JVM handles Thread.yield in a sensible fashion. This also keeps things well-behaved even if we are running on a uniprocessor JVM using a simple cooperative threading model. If all threads in the group are idling, they further progress to a hard wait phase, suspending until a new task is entered into the FJTaskRunnerGroup entry queue. These sleep mechanics are handled in the FJTaskRunnerGroup class. This opens up a few opportunities for further hand-optimizations.