我在 Java 中遇到了一些线程问题,我有三个线程 - thread1、thread2 和 thread3。那些在启动时正在执行一些任务,我想通过 thread1 停止这两个线程。我把thread1 for sleep(500)
,然后我停止了两个线程,但是两个线程的进程仍在运行。你知道怎么做吗?
问问题
30195 次
3 回答
21
你打算如何阻止他们?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();
或者,您也可以使用 a volatile boolean
(或AtomicBoolean)作为通信方式。
原子访问由主题线程提供volatile
并java.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!
请注意,最后两行可以按任意顺序出现。
于 2012-08-07T05:50:47.833 回答
9
你不能从另一个线程中停止一个线程。您只能要求线程自行停止,最好的方法是中断它。但是,被中断的线程必须协作,并通过停止执行来尽快响应中断。
这在有关并发的 Java 教程中有所介绍。
于 2012-08-07T05:49:54.153 回答
3
您可以:
- 有一些线程定期检查的布尔标志。如果它被改变,那么,它们会停止执行(注意这可能会导致竞争条件)
- 另一种选择是使用
ExecutorService
:
一个 Executor,提供管理终止的方法和可以生成 Future 以跟踪一个或多个异步任务的进度的方法。
于 2012-08-07T05:44:07.757 回答