Java线程的三种停止方法

一、阻塞中断和非阻塞中断

interrupt() 方法并不会立即执行中断操作,这个方法只会给线程设置一个为true的中断标志。
设置之后,则根据线程当前的状态进行不同的后续操作。
(1)如果,线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true而已(2)如果线程的当前状态处于阻塞状态,那么在将中断标志设置为true后,如果是 wait、sleep以及join 三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException ,这样受阻线程就得以退出阻塞的状态。
举例:一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了wait、join、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被程序会自动清除,重新设置为false
总结:调用线程类的interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。

public class TestThread1 {

    public static void main(String[] args) {
        MyRunnable1 myRunnable=new MyRunnable1();
        Thread thread=new Thread(myRunnable,"子线程");
        thread.start();
        try{
            //主线程休眠
            Thread.sleep(3000);
            //调用中断,true
           thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyRunnable1 implements Runnable{

    @Override
    public void run() {
      int i=0;
      while(true){
          System.out.println(Thread.currentThread().getName()+"循环第"+ ++i+"次");
          try{
            //判断线程的中断情况
                boolean interruptStatus=Thread.currentThread().isInterrupted();
                System.out.println(Thread.currentThread().getName()+"循环第"+ ++i+"次"+interruptStatus);
                Thread.sleep(1000);
                //非阻塞中断 只是设置标记位true
              //非阻塞中断 只是设置标记位true
              if(interruptStatus){
              //如果中断为true则退出
                  break;
              }
             
          } catch (InterruptedException e) {
              
              // 一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了
              // wait、join、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被程序会自动清除,重新设置为false
              System.out.println("阻塞中断"+Thread.currentThread().isInterrupted());//显示false并抛异常
              return;//不想返回还可继续写代码
          }
      }
    }
 
}
子线程循环第1false
子线程循环第2false
子线程循环第3false
阻塞中断false

二、stop方法停止

由于不安全,已经不使用了,因为stop会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 由于方法是同步的, 多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也会马上stop了,这样就产生了不完整的残废数据。

三、设置标记位停止

public class TestThread2_1 {
    public static void main(String[] args) throws InterruptedException {
        MyThreads my = new MyThreads();
        new Thread(my, "线程A").start();
        Thread.sleep(10000);
        //设置标记位
        //my.setFlag(false);

        //stop方法
        new Thread(my, "线程A").stop();
        System.out.println("代码结束");

    }
}

class MyThreads implements Runnable {
    private boolean flag = true;

    @Override
    public void run() {
        int i = 1;
        while (flag) {
            try {
                Thread.sleep(1000);
                System.out.println("第" + i + "次执行,线程名称为:" + Thread.currentThread().getName());
                i++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

你可能感兴趣的:(JavaSE)