0

I have two instances of a thread which is running continuously . How can i stop the very first instance of the thread . Please find the code below :-

public class Thread1 extends Thread {

 static volatile boolean bThreadStop = false ;  

  public void run() {
    while(!bThreadStop) {
      System.out.println("THREAD1");
      //BUSINESS LOGIC//

    }
  }
 public static void main(String[] args) {
   Thread1 t1 = new Thread1();
  t1.start();

      Thread1 t2 = new Thread1();
  t2.start();

  }
}

Here as per the above example , i need to stop t1 instance of Thread1 . Please suggest me how do I achieve the same .

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
trp86
  • 414
  • 1
  • 7
  • 21
  • possible duplicate of [What does the 'static' keyword do in a class?](http://stackoverflow.com/questions/413898/what-does-the-static-keyword-do-in-a-class) – Raedwald May 20 '14 at 19:15
  • See also http://stackoverflow.com/questions/3590000/what-does-java-lang-thread-interrupt-do – Raedwald May 20 '14 at 19:22

4 Answers4

1

The immediate answer to your question is that your flag is static so all instances of your Thread subclass see the same flag; making it instance-scope instead of static will mean the individual thread objects can be stopped separately. Also making the flag volatile will mean that the updates to the flag will be visible to the Thread subclass instances. Without volatile the flag checks can be optimized away by the JVM.

But using your own flag to cancel the thread isn't a good idea. There's a perfectly good flag already made for you and baked into the Thread class. In fact, it's better than anything you could come up with, because your thread can't stop sleeping or waiting to check your own flag, so once you set it the thread may take a while to respond. But if you use the interruption facility then the thread can check its own interrupted flag and stop sleeping or waiting right away.

Here's your example reworked to use interruption. In your example the output doesn't distinguish between Thread1 and Thread2, I added a name to help with that. Also I added a sleep to the thread (in order to cut down on the amount of stuff written to the console as well as to demonstrate interrupting a sleeping thread), and had the example cancel the second thread as well, after waiting long enough to make clear which thread was canceled first.

public class Thread1 extends Thread {

    public Thread1(String name) {
        super(name);
    }

    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println(getName());
                //BUSINESS LOGIC//
                Thread.sleep(1000L);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("thread " + getName() + " woke up");
        }
        System.out.println("thread " + getName() + " finished");
    }

    public static void main(String[] args) throws Exception {
        Thread1 t1 = new Thread1("t1");
        t1.start();
        Thread1 t2 = new Thread1("t2");
        t2.start();
        Thread.sleep(5000L);
        t1.interrupt();        // cancel the first thread
        Thread.sleep(5000L);
        t2.interrupt();        // cancel the second thread
    }
}

The output looks like:

t1
t2
t1
t2
t2
t1
t2
t1
t2
t1
thread t1 woke up
thread t1 finished
t2
t2
t2
t2
t2
thread t2 woke up
thread t2 finished

I have another example of thread interruption with more details here.

Community
  • 1
  • 1
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
0

How about making your bThreadStop flag an instance variable instead of making it static?

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

Your bThreadStop variable stops all your running threads. If you make it an instance variable (and even better, add a setter method) you'll be able to say t2.stop() and stop only t2.

Check out my answer to How to find and stop all currently running threads? as well, for some additional discussion about how to stop a thread properly.

From that discussion, StoppableRunnable provides the behavior you're looking for in a clean, thread-safe way:

public abstract class StoppableRunnable implements Runnable {
    private volatile boolean stopWork;
    private boolean done;

    public final void run() {
        setup();
        while(!stopWork && !done) {
            doUnitOfWork();
        }
        cleanup();
    }

    /**
     * Safely instructs this thread to stop working,
     * letting it finish it's current unit of work,
     * then doing any necessary cleanup and terminating
     * the thread.  Notice that this does not guarentee
     * the thread will stop, as doUnitOfWork() could
     * block if not properly implemented.
     */
    public void stop() {
        stopWork = true;
    }

    protected void done() {
        done = true;
    }

    protected void setup() { }
    protected void cleanup() { }

    /**
     * Does as small a unit of work as can be defined
     * for this thread.  Once there is no more work to
     * be done, done() should be called.
     */
    protected abstract void doUnitOfWork();
}
Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • Unless you need atomic `comareAndSet` or `getAndSet`, an `AtomicBoolean` is overkill. A simple `volatile boolean` does the job as well. But *if* you use an `AtomicBoolean` you should declare the variable holding it as `final`. – Holger May 21 '14 at 09:24
  • @Holger thanks for the feedback, I've updated the values as final, which makes sense. There was a discussion about whether `AtomicBoolean` was necessary on the answer I link to above, perhaps you'd care to weigh in there? I initially did not think `AtomicBoolean` was necessary either. – dimo414 May 21 '14 at 13:44
  • [This comment](http://stackoverflow.com/questions/15624296/how-to-find-and-stop-all-currently-running-threads/15624615#comment22175909_15624615) only says “You should make them volatile **or** AtomicBoolean”. And that’s right, you need either of them. Making it `volatile` is enough for this case. – Holger May 22 '14 at 10:53
  • Ah of course, that makes sense. That's what I get for not reading closely. Thanks! – dimo414 May 22 '14 at 13:08
0

As you can see there are many answers. I paste my contribution:

public class Thread1 extends Thread {

private volatile boolean threadRunning = true;  
private final int id;

public Thread1 (int id){
    this.id = id;
}

public void run() {
   while(threadRunning) {
       System.out.println("THREAD" + id);
   } 
}

public void stopTheThread(){
     threadRunning = false;
}

public static void main(String[] args) {
    Thread1 t1 = new Thread1(1);
    Thread1 t2 = new Thread1(2);

    t1.start();
    t2.start();

    t2.stopTheThread();
    t1.stopTheThread();
  }
}

I also like the Nathan Hughes implementation based on catch the InterruptedException.

Community
  • 1
  • 1
carlosvin
  • 979
  • 9
  • 22