Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用线程中断方法停止线程_Java_Multithreading_Concurrency_Java Threads_Interruption - Fatal编程技术网

Java 如何使用线程中断方法停止线程

Java 如何使用线程中断方法停止线程,java,multithreading,concurrency,java-threads,interruption,Java,Multithreading,Concurrency,Java Threads,Interruption,我正在尝试学习线程中断以及如何使线程在不调用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();

我正在尝试学习线程中断以及如何使线程在不调用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
我无法理解为什么睡眠被第二次打印,而中断的异常被第二次而不是第一次抛出。我已经检查了在java中使用volatile关键字来停止线程的帖子。但是我无法理解在这种情况下如何使用它,因为线程被中断停止。

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

因此,对sleep方法的第一次调用只是正常运行(interrupted标志尚未设置)。在此之后,您的代码不会对中断状态执行任何操作,直到第二次循环迭代,其中睡眠调用检测到中断状态并抛出异常


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

为了查看正在中断的线程,而不是第二次进入睡眠方法,更改运行方法中的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();
        }
    }
}
线程将休眠,然后设置自己的中断标志,然后检查标志并终止。只有在设置中断标志时线程处于睡眠状态时,线程#sleep方法才会抛出InterruptedException

不需要您的局部布尔变量。如果线程#sleep抛出InterruptedException(在本例中不会抛出,因为线程检查中断标志并离开while循环),则中断标志将被清除,在catch块中恢复它将允许while测试查看线程是否被中断


在实际程序中,线程将从另一个线程中断,线程没有理由中断自身(它可以返回)。

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

公共类测试实现可运行{ 公共布尔值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();
}
}

希望这会有帮助