0

I am using Threads (still..) for many stuff right now. I found many methods of thread that I would most likely use marked as deprecated.

Is there any chance to pause/resume thread with some triggers? Most people say to use wait.. but if I don't know the time ? I have some events that can happen after 5 minutes or after 2 hours...

Also .. another thing.

If I have a Thread .. it has an run() method. Now the Thread is started , run does what it has to do and then the Thread dies. Like forever ? The stuff from run() method is done so the Thread is ready to be taken out by garbage collector or is it just in some phase of disabled but still existing ?

Now you have a run method like that :

public void run(){
   while(running){
      //do stuff...
   }
}

If I switch the running to false, run method loops and stops because there is nothing more to do . Does this thread also die ? Can I for example say after some time I want to rerun this thread, so I just set the running to true again and call the run method, or do I have to recreate the Thread once again ?

  • 2
    For the first point, look for the Wait/Notify pattern http://www.programcreek.com/2009/02/notify-and-wait-example/ – Florent Aug 04 '15 at 16:56
  • 2
    For the second point : the thread will be taken out by garbage collector once not one has kept a reference on it (you may want to get some fields values). And you can't start a thread more than once : http://stackoverflow.com/questions/1215548/is-it-legal-to-call-the-start-method-twice-on-the-same-thread?answertab=active#tab-top – Florent Aug 04 '15 at 16:57
  • 1
    _then the `Thread` dies. Like forever?_ Yes. Forever. A `Thread` can only be started one time. – Solomon Slow Aug 04 '15 at 19:18
  • 1
    _run method [returns] because there is nothing more to do . Does this thread also die?_ Yes. A thread dies when its `run()` method returns, or when an exception is thrown out of its `run()` method. – Solomon Slow Aug 04 '15 at 19:21

2 Answers2

2

A Thread can only "live" once. When you create a Thread, you specify a Runnable instance as a target (if you don't, the thread targets itself—it implements Runnable and its default run() method does nothing). In either case, when the thread completes the run() method of its target Runnable, the thread dies.

In the example posed in the question, setting running to true after the run() method has returned will do nothing; the Thread can't be restarted after dying.

If you want to pause a thread, and reuse it later, there are a number of mechanisms. The most primitive is wait() and notify(). Rather than waiting for a specified period of time, you wait until a condition changes, like this:

abstract class Pausable implements Runnable {

  private final Object lock = new Object();

  private boolean pause = false;

  abstract void doSomething();

  @Override
  public void run() {
    while (cantering()) doSomething();
  }

  private boolean cantering() {
    synchronized (lock) {
      while (pause) {
        try { lock.wait(); }
        catch (InterruptedException ex) { 
          Thread.currentThread().interrupt();
          return false;
        }
      }
    }
    return true;
  }

  final void whoa() {
    synchronized(lock) {
      pause = true;
    }
  }

  final void giddyup() {
    synchronized(lock) {
      pause = false;
      lock.notify();
    }
  }

}

That's a lot of code, and it's fragile. I've been writing Java for 20 years and I'm not sure I got it right. That's why you should use the right tool from java.util.concurrency. For example, if you are waking up the thread to process a message, use a BlockingQueue, and let the consuming thread wait for messages to arrive on the queue. If you have tasks you want to perform asynchronously in response to some event, create an ExecutorService and submit the tasks. Even if you do want to use something like wait()/notify(), the concurrency package's Condition class gives you a lot more control over locking than intrinsic locks offer.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

Can I [...] and call the run method?

If you have a Thread t = ...;, and you write a call to t.run(), you probably are making a mistake.

A Thread is not a thread. A thread is a path of execution through your code. A Thread is an object with methods that can be used to create a new thread and manage its life-cycle.

You create the new thread by calling t.start().

Remember this mantra:

The start() method is the method that the library provides for your code to call when you want to start a new thread.

The run() method is the method that your code provides for the library to call in the new thread.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57