Is ThreadPoolExecutor safe?

Does ExecutorService provide thread safety?

I will send tasks from different threads to the same ThreadPoolExecutor, do I need to synchronize access to the executor before performing / sending tasks?

+63
java multithreading
Nov 09 '09 at 17:10
source share
5 answers

True, the JDK classes in question do not seem to provide an explicit guarantee of a thread-safe task. However, in practice, all implementations of the ExecutorService in the library are indeed thread safe. I think it is reasonable to depend on this. Since all code that implements these functions has been placed in the public domain, there is absolutely no motivation for anyone to completely rewrite it in a different way.

+27
Nov 09 '09 at 21:41
source share

(Unlike other answers) a security contract is documented : look in the javaadocs interface (as opposed to javadoc methods). For example, at the bottom of the ExecutorService javadoc you will find:

Memory Consistency Effects: Actions in the thread before the Runnable or Callable task is presented in the ExecutorService happens - before any actions taken by this task, which in turn will happen - before the result is received via Future.get ().

This is enough to answer this:

"Do I need to synchronize access to the executor before interacting / submitting tasks?"

No no. It's good to create and submit jobs to any (correctly implemented) ExecutorService without external synchronization. This is one of the main design goals.

ExecutorService is a parallel utility, that is, it is designed to work to the maximum extent, without requiring synchronization for performance. (Synchronization causes thread conflict, which can degrade multithreading performance - especially when scaling to a large number of threads.)

There is no guarantee that at what time in the future tasks will be completed or completed (some may even be executed immediately in the same thread that sent them), however, the worker thread was guaranteed to see all the effects that the feed stream performed right up to the time of submission. Therefore (the thread that is running), your task can also safely read any data created for its use without synchronization, thread-safe classes, or any other form of “secure publication”. The act of sending a task alone is sufficient to "securely publish" the input to the task. You just need to make sure that the input data will not be changed in any way during the execution of the task.

Similarly, when you return the result of a task back via Future.get() , the receiving stream will be guaranteed to see all the effects created by the worker’s stream (both in the returned result and in any side effect, the worker changes - maybe an error can be made) .

This contract also implies that more tasks are quite suitable for the tasks themselves.

"Does ExecutorService provide thread safety?"

Now this part of the question is much more general. For example, it was not possible to find any thread security contract operator about the shutdownAndAwaitTermination method - although I note that the code sample in Javadoc does not use synchronization. (Although, perhaps, there is a hidden assumption that the shutdown is initiated by the same thread that created the Executor, and not, for example, a work thread?)

BTW I would recommend the book "Java Concurrency In Practice" for a good grounder in the world of parallel programming.

+42
Sep 29 '11 at 11:00
source share

Your question is quite open: the entire ExecutorService interface ensures that some thread somewhere processes the sent instance of Runnable or Callable .

If the submitted Runnable / Callable refers to a common data structure accessible from other Runnable / Callable (potentially handled by simulated different threads), then it is your responsibility to ensure the safety of the threads in this data structure.

To answer the second part of your question, yes, you will have access to ThreadPoolExecutor before submitting any tasks; eg.

 BlockingQueue<Runnable> workQ = new LinkedBlockingQueue<Runnable>(); ExecutorService execService = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.SECONDS, workQ); ... execService.submit(new Callable(...)); 

EDIT

Based on Brian's comment, and in case I misunderstood your question: presenting tasks from multiple producer threads in an ExecutorService will usually be thread safe (despite the fact that it is not explicitly mentioned in the API, as far as I can tell). Any implementation that did not provide thread safety would be useless in a multi-threaded environment (since multiple vendors / multiple consumers are a fairly common paradigm), and that is exactly what ExecutorService (and the rest of java.util.concurrent ) was intended for.

+8
Nov 09 '09 at 17:13
source share

For ThreadPoolExecutor answer is simply yes. ExecutorService does not and does not guarantee that all implementations are thread safe and cannot be like an interface. These types of contracts go beyond the Java interface. However, ThreadPoolExecutor both clearly documented as thread safe. Moreover, ThreadPoolExecutor manages this job queue using java.util.concurrent.BlockingQueue , which is an interface that requires all implementations to be thread safe. Any java.util.concurrent.* BlockingQueue implementation can be safely accepted as thread-safe. Any non-standard implementation may not be, although it would be completely stupid if someone had to provide a BlockingQueue execution queue that was not thread safe.

So, the answer to your title question is clearly yes. This is probably the answer to the next question about your question, since there are some differences between them.

+6
Jul 01 '10 at
source share

Unlike what Luke Usherwood claims , this does not imply documentation that executorService implementations are guaranteed to be thread safe. Regarding the issue of ThreadPoolExecutor in particular, see Other Answers.

Yes, the connection between events and events is determined, but this does not mean anything about the safety of the threads of the methods themselves, as Miles commented. Luke Usherwood's response states that the former is sufficient to prove the latter, but the factual argument has not been made.

“Streaming security” can mean different things, but here is a simple counter example Executor (not an ExecutorService , but it doesn’t matter) that trivially meets the required-before action, but is not a -safe thread due to unsynchronized access to the count field.

 class CountingDirectExecutor implements Executor { private int count = 0; public int getExecutedTaskCount() { return count; } public void execute(Runnable command) { command.run(); } } 

Disclaimer: I am not an expert, and I found this question because I myself was looking for an answer.

0
Aug 21 '15 at 19:38
source share



All Articles