我正在尝试学习线程中断以及如何在不调用stop的情况下终止线程。
public class Test implements Runnable{
static Thread threadTest=null;
public static void main(String args[]){
System.out.println("Hello i am main thread");
Test thread= new Test();
threadTest= new Thread(thread);
threadTest.start();
}
private static void exitThread() {
threadTest.interrupt();
}
@Override
public void run() {
boolean run = true;
while (run) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
run = false;
}
}
}
}
输出
Hello i am main thread
Sleeping
Processing
Sleeping
我无法理解为什么第二次打印睡眠并且第二次抛出中断异常而不是第一次。我检查了使用volatile关键字来停止java中的线程的帖子。但我无法理解将在此场景中使用,因为线程会因中断而停止。
答案 0 :(得分:3)
为了看到线程被中断而不是第二次进入sleep方法,在run方法中更改while循环测试以检查中断标志:
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
线程将休眠,然后设置自己的中断标志,然后检查标志并终止。只有在设置了中断标志的情况下线程处于休眠状态时,Thread#sleep方法才会抛出InterruptedException。
不需要您的本地布尔变量。如果Thread#sleep抛出InterruptedException(在此示例中不会因为线程检查中断的标志并离开while循环),则清除中断标志,在catch块中恢复它允许while测试看到线程被打断了。
在实际程序中,线程会被另一个线程中断,线程没有理由自行中断(它可以直接返回)。
答案 1 :(得分:1)
调用Thread.interrupt()只为线程设置标志。它没有做任何其他事情。只有阻塞方法(通常声明抛出InterruptedException)才会响应正在设置的标志(通过抛出)。该标志是 sticky ,因为它一直保持设置直到被清除。
因此第一次调用sleep方法只是正常运行(中断的标志尚未设置)。之后,您的代码不会对中断状态执行任何操作,直到第二次循环迭代,其中sleep调用检测到中断状态并抛出异常。
您可以随时使用Thread.interrupted()或Thread.isInterrupted()来检查中断状态(请注意,如果已设置,则中断()也会清除中断状态。)
答案 2 :(得分:1)
在这里创建另一个线程测试类,但" main" 有自己的线程,因此您创建的新线程将被解释。 在这段代码中,您正在中断新创建的线程 Thread-0 而不是主线程,当您执行此代码时,您在进入方法之前使线程进入休眠状态 exitThread(),所以它正在显示处理,但是如果你在输入 exitthread()后试图让线程休眠,你会得到你的答案 就像在这段代码中一样:
public class Test实现Runnable { public boolean run = true;
@Override
public void run() {
while (run) {
try {
System.out.println("Sleeping...");
exitThread();
Thread.sleep(10000);
System.out.println("Processing...");
} catch (InterruptedException e) {
System.out.println("Thread intreputted " + e);
run = false;
}
}
}
private void exitThread() {
Thread.currentThread().interrupt();
if (Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread().getName()
+ " is intreputted");
else
System.out.println("alive");
}
public static void main(String[] args) {
System.out.println("hi I am current thread------>"
+ Thread.currentThread().getName());
Test test = new Test();
Thread thread = new Thread(test);
thread.start();
}
}
希望它会有所帮助