Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop a thread by another thread?

I have some struggle with threads in Java, I have three threads - thread1, thread2, and thread3. Those are doing some task when it started, I want to stop these two threads by thread1. I put thread1 for sleep(500), then I stop the both threads, but the process of two threads are still running. Do you have any idea how to do this?

like image 246
Mr.Cool Avatar asked Aug 07 '12 05:08

Mr.Cool


2 Answers

How're you attempting to stop them? Thread.stop? Be warned that this method is deprecated.

Instead, look into using some sort of flag for thread 1 to communicate to thread 2 and 3 that they should stop. In fact, you could probably use interrupts.

Below, Thread.interrupt is used to implement the coordination.

final Thread subject1 = new Thread(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
final Thread subject2 = new Thread(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final Thread coordinator = new Thread(new Runnable() {

  public void run() {
    try {
      Thread.sleep(500);
    } catch (InterruptedException ex) { }
    System.out.println("coordinator stopping!");
    subject1.interrupt();
    subject2.interrupt();
  }
});
subject1.start();
subject2.start();
coordinator.start();

Alternatively, you could also use a volatile boolean (or AtomicBoolean) as means of communicating. Atomic access provided by volatile and java.util.concurrent.atomic.* allow you to ensure mutation of the flag is seen by the subject threads.

final AtomicBoolean running = new AtomicBoolean(true);

final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {

  public void run() {
    while (running.get()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
subjects.submit(new Runnable() {

  public void run() {
    while (running.get()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {

  public void run() {
    System.out.println("coordinator stopping!");
    running.set(false);
    subjects.shutdown();
    coordinator.shutdown();
  }
}, 500, TimeUnit.MILLISECONDS);

Similarly, you could opt to, rather than use AtomicBoolean, use a field such as:

static volatile boolean running = true;

Better yet, if you take advantage of ExecutorServices, you can also program similar code as follows:

final ExecutorService subjects = Executors.newFixedThreadPool(2);
subjects.submit(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 1 stopped!");
  }
});
subjects.submit(new Runnable() {

  public void run() {
    while (!Thread.interrupted()) {
      Thread.yield();
    }
    System.out.println("subject 2 stopped!");
  }
});
final ScheduledExecutorService coordinator = Executors.newSingleThreadScheduledExecutor();
coordinator.schedule(new Runnable() {

  public void run() {
    System.out.println("coordinator stopping!");
    subjects.shutdownNow();
    coordinator.shutdown();
  }
}, 500, TimeUnit.MILLISECONDS);

This takes advantage of the fact that ThreadPoolExecutor.shutdownNow interrupts its worker threads in an attempt to signal shutdown.


Running any example, the output should be something to the effect of:

C:\dev\scrap>javac CoordinationTest.java

C:\dev\scrap>java CoordinationTest
coordinator stopping!
subject 1 stopped!
subject 2 stopped!

Note the last two lines can come in either order.

like image 128
obataku Avatar answered Oct 02 '22 21:10

obataku


You can't stop a thread from another thread. You can only ask the thread to stop itself, and the best way to do that is to interrupt it. The interrupted thread must collaborate, though, and respond to the interruption as soon as possible by stopping its execution.

This is covered in the Java tutorial about concurrency.

like image 27
JB Nizet Avatar answered Oct 02 '22 21:10

JB Nizet