3

我正在尝试学习线程中断以及如何使线程终止而不调用停止。

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

我无法理解为什么第二次打印 Sleeping 并且第二次而不是第一次抛出中断的异常。我已经检查了使用 volatile 关键字来停止 java 中的线程的帖子。但我无法理解如何使用它在这种情况下,线程因中断而停止。

4

3 回答 3

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 测试看到线程被中断。

在实际程序中,线程会被另一个线程中断,线程没有理由中断自己(它可以直接返回)。

于 2015-08-11T15:25:30.123 回答
1

调用 Thread.interrupt() 只是为线程设置一个标志。它不做任何其他事情。只有阻塞方法(通常声明抛出 InterruptedException)响应设置的标志(通过抛出)。该标志是粘性的,因为它保持设置直到它被清除。

所以第一次调用 sleep 方法只是正常运行(还没有设置中断标志)。之后,您的代码不会对中断状态执行任何操作,直到第二次循环迭代,其中 sleep 调用检测到中断状态并引发异常。

您可以随时使用 Thread.interrupted() 或 Thread.isInterrupted() 检查中断状态(请注意,如果已设置,interrupted() 也会清除中断状态)。

于 2015-08-08T15:51:50.413 回答
1

在这里您创建另一个线程测试 类,但 “main”有自己的线程,因此您创建的新线程被解释。在此代码中,您正在中断新创建的线程Thread-0而不是主线程,当您执行此代码时,您正在使线程在进入方法exitThread()之前进入睡眠状态,因此它正在显示处理,但是如果您尝试进入exitthread()后让线程休眠,您将得到答案,就像在这段代码中一样:

公共类测试实现 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();
}

}

希望它会有所帮助

于 2015-09-04T17:37:00.367 回答