mat_boy
mat_boy

Reputation: 13666

Java ExecutorService: should I put a lock before to use execute?

I have a class organized as follows:

public class MyClass {

   ExecutorService pool;

   public MyClass(){
     pool = ... //inited by a class that implements ExecutorService
   }

   public final void submit(Runnable run){
        pool.execute(run);
   }
}

Is the method submit thread safe or I should use a Lock-based system? E.g.

   ReentrantLock look  = new ReentrantLock();

   public final void submit(Runnable run){
        lock.lock();
        try{ pool.execute(run); } finally{lock.unlock();}
   }

Upvotes: 5

Views: 5527

Answers (2)

wmorrison365
wmorrison365

Reputation: 6288

This depends on how your ExecutorService is accessed or how your MyClass is created. If an instance of MyClass is created in a single thread and the #pool ivar is also created in a single thread then this class is thread-safe and your use of #pool is threadsafe.

However, if your MyClass can exist across multiple threads (such as first accessed through a singleton, shared factory or shared list - i.e. not new MyClass()) then it is not thread-safe. This is because multiple threads could access your Myclass instance and its single #pool ivar. Calling submit could be done but multiple threads at once and so the state of your Myclass instance or pool could be compromised. In this case, your MyClass#submit should be synchronised or managed by locks. As it's a petite method, I'd suggest just synchronising #submit.

Likewise, if your MyClass instance is created in this thread but #pool is not created as new in this thread (pool = new AnExecutorPoolType(...); then this class would again not be threadsafe. The pool may again be accessed from another source(as above) that is available across multiple threads. If that's the case then there is a risk of it being left in an inconsistent state by multiple thread accesses. In this case, the pool#execute method should be synchronised (or through a synchronised block guarding ivar access) or managed through locks.

Upvotes: 2

assylias
assylias

Reputation: 328568

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.

Upvotes: 8

Related Questions