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

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

你是怎么试图阻止他们的? 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(); 

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

 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

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