1

When we call start() on a Thread by passing a Runnable object as argument, can we pass the same Runnable reference to start multiple threads?

public class MyMain {
    public static void main(String[] args) {
        MyRunnableImpl impl = new MyRunnableImpl();
        new Thread(impl).start();
        new Thread(impl).start();
    }
}
Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
Ullas
  • 837
  • 3
  • 10
  • 14
  • 4
    "*It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.*" This might throw `IllegalThreadStateException`. – Maroun May 18 '13 at 13:27
  • http://stackoverflow.com/questions/9849109/passing-single-runnable-object-to-multiple-thread-constructors – Adam Siemion May 18 '13 at 13:29
  • 2
    @MarounMaroun: I don't see how that's relevant. The OP is using the same Runnable for multiple threads, not starting the same thread multiple times. – Jon Skeet May 18 '13 at 13:37
  • @JonSkeet Yes. I've just noticed that. My bad. I didn't notice that he made an new instance of the Thread and called start on it. – Maroun May 18 '13 at 13:37

1 Answers1

7

Yes, you can do this when your Runnable is implemented accordingly.

But you have to be careful your Runnable implementation does not contain a mutable state. You can control this in your own implementations, but the Runnable contract does not specify.

// can be used for multiple Threads
class StatelessRunnable {
  public void run() {
    doSomething();
  }
}

// may go bang on the second execution -> use two instances
class StatefulRunnable {
  volatile boolean canRun = true;
  public void run() {
    if(!canRun) throw new IllegalStateException();
    canRun = false;
  }
}

In the above sample you see that you can use StatelessRunnable for as many threads as you like. In fact you could even make it a singleton. StatefulRunnable in contrast can be run only once per instance.

Shared State

Reading Jon's answer I realised there may be scenarios where you actually want to share a state of two Runnable instances. Of course a stateful Runnable instance is not always bound to fail with multiple threads, but this is much more trickier to get right than a stateless one.

// willingly share state over threads
class WillinglyStatefulRunnable {
  final BlockingQueue<Object> sharedObjects = new BlockingQueue<Object>();
  public void run() {
    sharedObjects.offer(new Object());
  }
}

The above example shows how you could work on a single collection sharedObjects with multiple threads.

Literature Sidenote:

Item 15 in Joshau Bloch's Effective Java says Minimize Mutabilty. This chapter - in case you have access to the book - addresses similar points in a much more general context. Shortly summarised he states that immutable objects make it easier to reuse instances and reduce the potential of illegal states.

Community
  • 1
  • 1
Matthias Meid
  • 12,455
  • 7
  • 45
  • 79
  • i have just started reading java concurrency in practise, so expect few more questions in future..Thanks.. – Ullas May 18 '13 at 13:42
  • 1
    I know this is just example code to illustrate your answer, but, in the `StatefulRunnable`, shouldn't the `boolean canRun` be volatile, if it is going to be accessed by multiple threads? – afsantos May 18 '13 at 14:06
  • 1
    Theoretically, `StatefulRunner` _may_ be able to be run more than once, since there is a race condition between checking `canRun` and setting it to `false`. If you want to ensure it can run only once, use an `AtomicBoolean`. – NamshubWriter May 18 '13 at 15:41