美文网首页
多线程系列09-线程终止与线程中断

多线程系列09-线程终止与线程中断

作者: Sandy_678f | 来源:发表于2019-07-22 15:51 被阅读0次

线程终止:
在Thread类中JDK给我们提供了一个终止线程的方法stop(); 该方法一经调用就会立即终止该线程,并立即释放对象锁。如果当一个线程执行一半业务而调用了该方法,可能就会产生数据不一致问题。
线程中断:
线程中断就是让目标线程停止执行,但它不会使线程立即终止,而是给线程发送一个通知,告诉线程jvm希望你退出执行,至于目标线程何时退出,则完全由它自己决定(如果立即停止,会造成与stop一样的问题)。

JDK中线程中断的3个相关方法:

//线程中断 
public void interrupt(){}
//判断线程是否中断
public boolean isInterrupted() {}
//判断线程是否中断,并清除当前中断状态
public static boolean interrupted(){}
  1. 中断处于阻塞状态(sleep() / join ()/wait())的线程
 public static native void sleep(long millis) throws InterruptedException;

看源码可知sleep() 方法 InterruptedException 中断异常,该异常不是运行时异常,所以需要捕获它,当线程在执行sleep()时,如果发生线程中断,这个异常就会产生。该异常一旦抛出就会清除中断状态。
并且,对InterruptedException的捕获务一般放在while(true)循环体的外面,这样,在产生异常时就退出了while(true)循环。否则,InterruptedException在while(true)循环体之内,就需要额外的添加退出处理。
常用方式:

@Override
public void run() {
    try {
        while (true) {
            // 执行任务...
        }
    } catch (InterruptedException ie) {  
        // 由于产生InterruptedException异常,退出while(true)循环,线程终止!
    }
}
  1. 中断处于运行状态的线程
    通常,我们通过“标记”方式中断处于“运行状态”的线程。包括“中断标记”与“额外添加标记”。
    中断标记方式:
@Override
public void run() {
    while (!isInterrupted()) {
        // 执行任务...
    }
}

额外添加标记:

private volatile boolean flag= true;
protected void stopTask() {
    flag = false;
}

@Override
public void run() {
    while (flag) {
        // 执行任务...
    }
}

综上,比较通用的终止线程的方式:

@Override
public void run() {
    try {
        // 1. isInterrupted()保证,只要中断标记为true就终止线程。
        while (!isInterrupted()) {
            // 执行任务...
        }
    } catch (InterruptedException ie) {  
        // 2. InterruptedException异常保证,当InterruptedException异常产生时,线程被终止。
    }
}

示例:

public class Demo1 {

    static class MyThread extends Thread{
        public MyThread(String name){
            super(name);
        }

        @Override
        public void run(){
            try{
                int i = 0;
                while(!isInterrupted()){
                    Thread.sleep(100);
                    i++;
                    System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i);
                }
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException.");
            }
        }

    }

    public static void main(String[] args) {

        try {
            MyThread myThread = new MyThread("myThread");
            System.out.println(myThread.getName() +" ("+myThread.getState()+") is new.");

            myThread.start();
            System.out.println(myThread.getName() +" ("+myThread.getState()+") is started.");

            //主线程休眠300ms,然后给主线程发出"中断"指令
            Thread.sleep(300);
            myThread.interrupt();
            System.out.println(myThread.getName() +" ("+myThread.getState()+") is interrupted.");

            //主线程休眠300ms,然后查看myThread状态
            Thread.sleep(300);
            System.out.println(myThread.getName() +" ("+myThread.getState()+") is interrupted now.");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

相关文章

网友评论

      本文标题:多线程系列09-线程终止与线程中断

      本文链接:https://www.haomeiwen.com/subject/uekwlctx.html