如何通过另一个线程停止线程?

Mr.*_*ool 7 java multithreading

我在Java中遇到了一些线程,我有三个线程 - thread1,thread2和thread3.当它开始时,它们正在做一些任务,我想通过thread1停止这两个线程.我把thread1用于sleep(500),然后我停止两个线程,但两个线程的进程仍在运行.你知道怎么做吗?

old*_*inb 19

你是怎么试图阻止它们的?Thread.stop?请注意,此方法已弃用.

相反,请考虑使用线程1的某种标志来与线程2和3通信它们应该停止.实际上,你可能会使用中断.

下面,Thread.interrupt用于实现协调.

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();
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用volatile boolean(或AtomicBoolean)作为通信方式. 由主题线程提供的原子访问volatilejava.util.concurrent.atomic.*允许您确保标志的突变.

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);
Run Code Online (Sandbox Code Playgroud)

同样,您可以选择AtomicBoolean使用以下字段,而不是使用:

static volatile boolean running = true;
Run Code Online (Sandbox Code Playgroud)

更好的是,如果您利用ExecutorService,您还可以编写类似的代码,如下所示:

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);
Run Code Online (Sandbox Code Playgroud)

这利用了ThreadPoolExecutor.shutdownNow中断其工作线程以试图发出关闭信号的事实.


运行任何示例,输出应该是以下效果:

C:\dev\scrap>javac CoordinationTest.java

C:\dev\scrap>java CoordinationTest
coordinator stopping!
subject 1 stopped!
subject 2 stopped!
Run Code Online (Sandbox Code Playgroud)

请注意,最后两行可以按任意顺序排列.


JB *_*zet 8

你无法阻止来自另一个线程的线程.你只能要求线程自行停止,最好的方法是中断它.但是,中断的线程必须协作,并通过停止执行来尽快响应中断.

有关并发性Java教程中对此进行了介绍.