Is Executorservice (Specifically Threadpoolexecutor) Thread Safe

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 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().

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

  1. 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.


  1. 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



Leave a reply



Submit