所有答案都是关于如何停止某些线程的循环,但是如果我没有循环但是我还想在执行/处理所有行之前停止一个线程呢?
例如,我有一个通常运行7-10秒然后死掉(终止)的线程:
mThread = new Thread(new Runnable() {
@Override
public void run() {
// some code here
// some here
// some here
// some here
// some here
// all lines takes about 7-10 seconds
}
});
如果我开始一个线程,并且在2或3秒后我需要停止它,然后该怎么做并且不要等待10秒?
答案 0 :(得分:3)
如果您的线程没有被阻止,并且实际上正在处理内容,那么中断它可能没有帮助。您可以对线程进行编码以检查当前线程上的中断标志,然后在看到该标志已设置时停止。
这是检查当前线程是否已被中断的方法。
Thread.currentThread().isInterrupted();
所以你必须像这样编写你的线程......
mThread = new Thread(new Runnable() {
@Override
public void run() {
// some code here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
if (Thread.currentThread().isInterrupted()) return;
// some here
// all lines takes about 7-10 seconds
}
});
然后你可以继续中断mThread,它会产生影响。虽然它仍将继续处理当前的some here
步骤。
答案 1 :(得分:3)
首选方法是在线程中实现停止机制。您也可以尝试观察interrupt
标志。您可以使用Thread#interrupt
方法从外部中断,并且线程可以使用Thread#isInterrupted
和Thread#interrupted
检查标记(请参阅Thread的文档)。
没有办法强制线程从外部停止,而线程实际上没有实现逻辑。有Thread#stop
方法,但已弃用,绝不应使用。来自documentation:
<强>已过时即可。此方法固有不安全。使用
Thread.stop
停止某个线程会导致它解锁所有已锁定的监视器(这是未经检查的ThreadDeath
异常向上传播的自然结果)。如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 stop的许多用法应该被简单修改某个变量的代码替换,以指示目标线程应该停止运行。目标线程应该定期检查此变量,并且如果变量指示它将停止运行,则以有序的方式从其run方法返回。如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。有关详细信息,请参阅Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?。
您可以像这样修改线程:
public class MyThread implements Runnable {
private volatile boolean mShouldStop = false;
public void shutdown() {
mShouldStop = true;
}
@Override
public void run() {
// First line ...
if (mShouldStop) return;
// Second line ...
if (mShouldStop) return;
// Third line ...
if (mShouldStop) return;
}
}
因此,您需要定期检查标志,然后手动中止。
通常这样的线程有某种while (true)
循环。在这种情况下,你可以做到更容易:
@Override
public void run() {
while (!mShouldStop) {
// Do something ...
}
}
根据您的应用程序,您可能会将中断标志解释为线程关闭的信号。然后你的代码看起来像
@Override
public void run() {
while (!Thread.interrupted()) {
// Do something ...
}
}
mShouldStop
必须为volatile
,以确保Thread
正确更新。请参阅Oracle的教程Atomic Access。
答案 2 :(得分:0)
您使用mThread.interrupt()
中断线程。但是,为了使其正常工作,您的线程需要检查中断状态(通过休眠)。看看这个thread。
有关详细信息,请参阅此thread。
答案 3 :(得分:0)
您需要检查线程中的中断状态。像这样的东西
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class ThreadInterruptor {
private static class Worker implements Runnable {
@Override
public void run() {
while (true) {
IntStream.range(0, Short.MAX_VALUE).forEach(i ->noop());
if (Thread.currentThread().isInterrupted()) {
System.out.println("i got interrupted");
break;
}
}
}
private void noop(){}
}
public static void main(String[] args) throws Exception{
Thread thread = new Thread(new Worker());
thread.start();
TimeUnit.SECONDS.sleep(5);
thread.interrupt();
}
}