繁体   English   中英

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

[英]How to stop a thread by another thread?

我在Java中的线程上有些挣扎,我有三个线程-线程1,线程2和线程3。 那些启动时正在执行某些任务,我想通过thread1停止这两个线程。 我将thread1设置为sleep(500) ,然后停止了两个线程,但是两个线程的进程仍在运行。 你有什么想法吗?

您如何试图阻止他们? Thread.stop 警告该方法已弃用。

而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。 实际上,您可能会使用interrupts

下面,使用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();

或者,您也可以使用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);

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

static volatile boolean running = true;

更好的是,如果您利用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);

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


运行任何示例,输出应具有以下效果:

C:\dev\scrap>javac CoordinationTest.java

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

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

您不能停止另一个线程中的一个线程。 您只能要求线程停止运行,而最好的方法是中断它。 但是,被中断的线程必须协作,并通过停止其执行来尽快响应中断。

Java并发教程中对此进行了介绍

您可以:

  • 有一些布尔标志,线程定期检查。 如果更改,则它们将停止执行(请注意,这可能会导致竞争状况)
  • 另一种选择是使用ExecutorService

一个执行程序,提供用于管理终止的方法以及可以生成用于跟踪一个或多个异步任务进度的Future的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM