plastilino
plastilino

Reputation: 31

Unexpected deadlock in Executor

I found an unexpected deadlock while running tasks in a ThreadPoolExecutor.

The idea is a main task that launches a secondary task that changes a flag. The main task halts until the secondary task updates the flag.

I'd like to know:

Upvotes: 2

Views: 1747

Answers (1)

Antoniossss
Antoniossss

Reputation: 32507

How do you expect for this to work on threads count <2 if

  • You have only 1 executor thread
  • first tast adding secondary task to the executor queue and WAITS for it to start

Tasks are fetched from the queue by executor service when there are free executors in pool. In you case (<2) executor thread is never released by first task. There is no deadlock issue here.

EDIT:

Ok, I'v dug up some info and this is what I have found out. First of all some info from ThreadPoolExecutor

Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:

If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.
If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.
If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

Ok and now as for queuess offer methods

SyncQueue:

Inserts the specified element into this queue, if another thread is waiting to receive it.

LinkedBlockingQueue

Inserts the specified element into this queue, waiting if necessary for space to become available.

return value of offer method determines whetever new task will be queued or ran in new thread.

As LinkedBlockingQueue enqueues new task because it can as there is enought capacity, task is enqueued and no new threads are spawn. However SyncQueu will not enqueue another task, as there is no other threads that are waiting for something to be enqueued (offer returns false as task is not enqueued) and thats why new executor thread will be spawned.

If you read javadocs for ThreadPoolExecutor LinkedBlockingQueue and SynchronousQueue + check implementation of execute method, you will get to the same conclusion.

So you were wrong, there is explenation in documentation :)

Upvotes: 6

Related Questions