Java并发编程之线程的中止

简介

通常状况下,线程执行完成后就会结束,但有的时候咱们可能须要在它正常执行完成前就中止它,能够考虑使用如下三种方法:java

  1. 使用Thread中的stop方法,这个方法已经被标为已废弃,不推荐使用,缘由是stop方法会当即终止线程并释放持有的锁,在多线程的状况下可能会致使数据不一致的问题。多线程

  2. 自定义一个标志,经过修改这个标志的值来让线程判断是否须要退出。ide

  3. 使用线程中断机制。线程

后面两种方法有点相似,都是经过给线程发一个通知,而后让线程去判断是否能够结束,而不是像stop方法那样暴力的终止线程,下面介绍下后两种方法的使用和区别。code

使用自定义标志中止线程

这里定义了一个变量flag,主线程会在3秒后将flag设置为false,当flag为false的时候,run方法里面的循环就会结束,线程也就中止了。it

public class MyThread extends Thread{
    volatile boolean flag = true;

    @Override
    public void run() {
        while (flag){
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.flag = false;
    }
}

使用线程中断机制中止线程

线程中断有关的三个方法:io

  1. interrupt(),中断线程。
  2. isInterrupted(),判断线程是否被中断。
  3. interrupted,Thread类的静态方法,判断线程是否被中断,并清除中断状态。

这种方式与前面那种方式很相似,只是由判断flag变为判断线程是否被中断。class

public class MyThread extends Thread{

    @Override
    public void run() {
        while (!isInterrupted()){
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.interrupt();
    }
}

自定义标志和线程中断机制的区别

前面介绍的两种方式使用起来很是的相似,可是中断机制要更强,由于当循环体内出现了Thread.sleep()或者wait()这样的操做时,自定义标志的方式就只能等阻塞结束。而这两个方法是能够响应中断的。变量

1.主线程在3秒后更改flag状态,可是线程还处于sleep()阻塞中,须要等到sleep()时间结束也就是10秒后线程才中止。循环

public class MyThread extends Thread{
    volatile boolean flag = true;

    @Override
    public void run() {
        while (flag){
            try {
                Thread.sleep(10000);
            }catch (InterruptedException ex){
                ex.printStackTrace();
            }
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.flag = false;
    }
}

2.处于sleep()阻塞中的线程若是被中断就会抛出InterruptedException异常,此时它会清除中断标记,因此须要捕获该异常,并在异常处理中再次设置中断标记。

public class MyThread extends Thread{

    @Override
    public void run() {
        while (!isInterrupted()){
            try {
                Thread.sleep(10000);
            }catch (InterruptedException ex){
                //从新设置中断标记
                interrupt();
            }
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.interrupt();
    }
}
相关文章
相关标签/搜索