Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ExecutorService (specifically ThreadPoolExecutor) thread safe?

Does the ExecutorService guarantee thread safety ?

I'll be submitting jobs from different threads to the same ThreadPoolExecutor, do I have to synchronize access to the executor before interacting/submitting tasks?

like image 429
leeeroy Avatar asked Nov 09 '09 17:11

leeeroy


People also ask

Can threads be submitted to ExecutorService?

Once the thread has delegated the task to the ExecutorService , the thread continues its own execution independent of the execution of that task. The ExecutorService then executes the task concurrently, independently of the thread that submitted the task.

Is Python ThreadPoolExecutor thread safe?

ThreadPoolExecutor Thread-Safety Although the ThreadPoolExecutor uses threads internally, you do not need to work with threads directly in order to execute tasks and get results. Nevertheless, when accessing resources or critical sections, thread-safety may be a concern.

What are the advantages of using ExecutorService instead of creating threads directly?

ExecutorService abstracts away many of the complexities associated with the lower-level abstractions like raw Thread . It provides mechanisms for safely starting, closing down, submitting, executing, and blocking on the successful or abrupt termination of tasks (expressed as Runnable or Callable ).

What is the difference between executor and ExecutorService?

Executor just executes stuff you give it. ExecutorService adds startup, shutdown, and the ability to wait for and look at the status of jobs you've submitted for execution on top of Executor (which it extends).


2 Answers

(Contrary to other answers) the thread-safety contract is documented: look in the interface javadocs (as opposed to javadoc of methods). For example, at the bottom of the ExecutorService javadoc you find:

Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task, which in turn happen-before the result is retrieved via Future.get().

This is sufficient to answer this:

"do I have to synchronize access to the executor before interacting/submitting tasks?"

No you don't. It is fine to construct and submit jobs to any (correctly implemented) ExecutorService without external synchronisation. This is one of the main design goals.

ExecutorService is a concurrent utility, which is to say that it is designed to operate to the greatest extent without requiring synchronisation, for performance. (Synchronisation causes thread-contention, which can degrade multi-threading efficiency - particularly when scaling up to a large number of threads.)

There is no guarantee about at what time in the future the tasks will execute or complete (some may even execute immediately on same thread that submitted them) however the worker thread is guaranteed to have seen all effects that the submitting thread has performed up to the point of submission. Therefore (the thread that runs) your task can also safely read any data created for its use without synchronisation, thread-safe classes or any other forms of "safe publication". The act of submitting the task is itself sufficient for "safe publication" of the input data to the task. You just need to ensure that the input data won't be modified in any way while the task is running.

Similarly, when you fetch the result of the task back via Future.get(), the retrieving thread will be guaranteed to see all effects made by the executor's worker thread (in both the returned result, plus any side-effect changes the worker-thread may have made).

This contract also implies that it is fine for the tasks themselves to submit more tasks.

"Does the ExecutorService guarantee thread safety ?"

Now this part of the question is much more general. For example could not find any statement of a thread-safety contract about the method shutdownAndAwaitTermination - although I note that the code sample in the Javadoc does not use synchronisation. (Although perhaps there's a hidden assumption that the shutdown is instigated by the same thread that created the Executor, and not for example a worker thread?)

BTW I'd recommend the book "Java Concurrency In Practice" for a good grounder on the world of concurrent programming.

like image 76
Luke Usherwood Avatar answered Oct 02 '22 16:10

Luke Usherwood


It's true, the JDK classes in question don't seem to make an explicit guarantee of thread-safe task submission. However, in practice, all ExecutorService implementations in the library are indeed thread-safe in this way. I think it's reasonable to depend on this. Since all the code implementing these features was placed in the public domain, there's absolutely no motivation for anyone to completely rewrite it a different way.

like image 31
Kevin Bourrillion Avatar answered Oct 02 '22 14:10

Kevin Bourrillion