Is ExecutorService (specifically ThreadPoolExecutor) thread safe?
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.
Executor suitable for non thread-safe code
If the code really needs only an Executor
, and not a (much more complex) ExecutorService
, it is easy to implement your own single-threaded executor that does precisely what is needed. The API documentation of Executor
even shows you how to do so:
class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
If the code does need an ExecutorService
, it is possible that the single thread executor provided byExecutors.newSingleThreadExecutor()
is adequate for testing the non thread-safe code, despite the resulting program having two threads (the thread running the unit tests and the single thread-pool thread of the ExecutorService
). This is because an ExecutorService
must provide the following thread-safety guarantees:
- Actions in a thread prior to the submission of a
Runnable
orCallable
task to anExecutorService
happen-before any actions taken by that task, - which in turn happen-before the result is retrieved via
Future.get()
.
Therefore, if the thread running the unit tests does a Future.get()
for all the submitted tasks, all changes to any shared objects will have been safely published, and the thread running the unit tests may safely examine those shared objects.
Java ExecutorService: should I put a lock before to use execute?
No you don't need the lock when calling ExecutorService#submit.
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().
or when calling Executor#execute:
Memory consistency effects: Actions in a thread prior to submitting a Runnable object to an Executor happen-before its execution begins, perhaps in another thread.
Need for thread safety when using a SinglethreadExecutor
Your requests will be passed to a different thread to be executed. Even if this thread doesn't access shared data structures, the passing of the request to the thread and the returning of the result need to be properly synchronized.
If you use one of the submit
or invoke
methods which use a Future
object for returning the results, you can assume that the appropriate synchronization is performed. The javadoc for ExecutorService
says this:
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().
In short, if the requests / tasks don't use shared data structures and you use the interface methods provided, then you should be OK.
ThreadPoolExecutor Vs ExecutorService for service time out use cases
- It was recommended to use ExecutorSevice with Executors.XXX methods. If I use Executors.XXX() methods, do I have capabilities to set RejectionHandler, BlockingQueue size etc? If not, Do I have to fall back on ThreadPoolExecutor?
No, you can't specify these things via Executors
factory methods. However, take a look at the source code of Executors
: you will see that its newXXX
methods simply wrap calls to create ThreadPoolExecutor
instances.
As such, there is no particular advantage to using Executors
, aside from the convenience of not having to specify many of the parameters. If you need to specify these additional capabilities, you will need to create the ThreadPoolExecutor
instances directly.
- Does ExeuctorService offers unbounded queue? I am implementing Timeout framework between two services. Which one is best option between these two? Or Do I have other best option (e.g. CountDownLatch etc.)
ExecutorService
is an interface: it offers you nothing by way of implementation details such as unbounded queues.
How can I avoid that each Thread creates a different pool?
Your code already uses a single threadpool. However if your class might have several instances and you want those to all share the same threadpool then assign it as a static variable.
Though I would also pull out the shutdown code to its own method too now. Also don't poll isTerminated, use awaitTermination.
Something like the following:
public class Station {
private Arrivals arrivals;
private Vehicle k;
private ListPumps lp;
private static ExecutorService executor = Executors.newFixedThreadPool(3);
public void startWork(Pump p) {
Runnable w = new Work(p);
executor.execute(w);
}
public static synchronized void shutdown() {
executor.shutdown();
if(executor.awaitTermination(60, TimeUnit.SECONDS))
System.out.println("Finished all threads");
else
System.out.println("Executor shutdown timed out");
}
}
Related Topics
Hashcode and Equals for Hashset
JPA Query.Getresultlist() - Use in a Generic Way
Sum All the Elements Java Arraylist
Any Recommended Java Profiling Tutorial
Why Do I Need a Functional Interface to Work with Lambdas
Spring Security's Securitycontextholder: Session or Request Bound
Is There a Commonly Used Rational Numbers Library in Java
How to Search in a List of Java Object
Java: Global Exception Handler
Why Does Java Code with an Inner Class Generates a Third Someclass$1.Class File
How to Set an Environment Variable at Runtime from Java
Find Out What Jvm Eclipse Is Running On
How to Disable Loggers of a Class or of Whole Package
Calling Base Class Overridden Function from Base Class Method
Is There a Sophisticated File System Monitor for Java Which Is Freeware or Open Source