【问题标题】:how to stop a thread with thread interrupt method如何使用线程中断方法停止线程
【发布时间】:2015-10-31 22:53:49
【问题描述】:

我正在尝试学习线程中断以及如何在不调用 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

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

【问题讨论】:

    标签: java multithreading concurrency java-threads interruption


    【解决方案1】:

    为了看到线程被中断而不是第二次进入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 测试看到线程被中断。

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

    【讨论】:

      【解决方案2】:

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

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

      }

      希望对你有帮助

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多