interrupted、isInterrupted

对于线程来说,动起来不是什么问题,但是如何让它停下来,就需要一些处理。

虽然stop、suspend、resume都可以使线程停下来,但是官方是不建议的,现在已经废弃了。

interrupt方法仅仅只是打了一个停止标记。

判断线程是否停止状态

  • interrupt
  • isInterrupted
public class Test148 {
        public static void main(String[] args) {
            MyThread33 mm = new MyThread33();
            Thread t = new Thread(mm);
            t.start();
            t.interrupt();
            System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());//当前运行的是main,故false
            System.out.println("t.interrupted()"+t.interrupted());
            System.out.println("Thread.currentThread().isInterrupted()"+Thread.currentThread().isInterrupted());
            System.out.println("t.isInterrupted()"+t.isInterrupted());//对线程t判断是否中断状态,true。
        }
}

class MyThread33 extends Thread{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 0;i<10000;i++) {
            System.out.println("*");
        }
    }

}

运行结果如下:

这里写图片描述

我们来分析一下,我们给线程t设置停止标志,interrupted方法,只是对当前正在运行的线程,判断是否中断状态,它不管调用对象;isInterrupted,是针对调用线程对象,来判断是否中断状态。

修改上述代码:

    Thread.currentThread().interrupt();//我们给main线程设置中断标志
            System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());
            System.out.println("Thread.currentThread().interrupted()"+Thread.currentThread().interrupted());

我们发现执行下来,第一个是true,因为当前的正在运行的线程对象是main,第二个是false,这里实际上,执行interrupt,如果是中断状态,会自动清除,所以是false。而isInterrupted,就不具备清除中断标志。验证代码修改如下:

            t.interrupt();
            System.out.println("t.isInterrupted()"+t.isInterrupted());//true
            System.out.println("t.isInterrupted()"+t.isInterrupted());//true

牛刀小试

看看结合上面讲的如何让线程停下来。

public class Test148 {
        public static void main(String[] args) {
            MyThread33 mm = new MyThread33();
            Thread t = new Thread(mm);
            t.start();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t.interrupt();
        }
}

class MyThread33 extends Thread{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 0;i<10000;i++) {
            //interrupted  上面讲过是针对当前正在运行的线程,判断是否有中断标志,这里的this,指的是
            //MyThread33线程的实例,也就是mm。但是这时正在运行时线程t,
            //看谁调用start。interrupted又不管谁调用,它只在现在正在运行的
            System.out.println(this.getName());//Thread-0
            if(Thread.currentThread().interrupted()) {
                System.out.println("我要停止了");
                break;

            }
            System.out.println(i);
        }
    }

}

在上面代码,还存在一个问题,就是如果for循环外面还有语句,那么这样的话,下面的语句还是会执行。在上面的代码做修改:

try {
        for(int i = 0;i<10000;i++) {
            //interrupted  上面讲过是针对当前正在运行的线程,判断是否有中断标志,这里的this,指的是
            //MyThread33线程的实例,也就是mm。但是这时正在运行时线程t,
            //看谁调用start。interrupted又不管谁调用,它只在现在正在运行的
            System.out.println(this.getName());//Thread-0
            if(Thread.currentThread().interrupted()) {
                System.out.println("我要停止了");
                throw new InterruptedException();
            }
            System.out.println(i);
        }
        System.out.println("我在for外面");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

我们把执行体中需要执行的代码,放到一个异常的try中,当捕获这个异常的时候,程序代码是try中是不会往下执行,处理上面的问题,但是异常程序会让程序崩了。

线程在Sleep中停止

在这个操作中,一定要保证线程在Sleep的状态下,你去给他设置了停止标志,才会触发异常,如果Sleep状态结束,主线程才执行t.interrupt(),是不会影响的。

MyTask111 mt = new MyTask111();
        Thread t  = new Thread(mt);
        t.start();
        /*try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
        t.interrupt();
    }
}
class MyTask111 implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("我停止了");
            e.printStackTrace();
        }
    }

}

我们之前就说过,Java已经抛弃stop方法,为啥呢,使用该方法停止线程,会造成数据不一致的问题,只要执行stop语句,是不管线程执行到哪,它立马停止。下面模拟该问题的发生。

public class Account {
    private String username="a";
    private String userpassword = "aa";
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getUserpasswword() {
        return userpassword;
    }
    public void setUserpasswword(String userpasswword) {
        this.userpassword = userpasswword;
    }

    public String toString(String username,String userpassword) {
        this.username = username;
        try {
            Thread.sleep(3000);//通过睡眠拖时间,给时间让主线程执行到stop
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.userpassword  = userpassword;
    return  username+"   "+userpassword;
    }

}
public class Test159 {
   public static void main(String[] args) {
       Account a = new Account();
       MyThread990 mt = new MyThread990(a);
       Thread t = new Thread(mt);
       t.start();
       try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
       t.stop();
       System.out.println(a.getUsername()+"   "+a.getUserpasswword());
  }
}
class MyThread990 implements Runnable{
    private Account  useraccound;


    public MyThread990(Account useraccound) {
        super();
        this.useraccound = useraccound;
    }


    @Override
    public void run() {
        // TODO Auto-generated method stub
            useraccound.toString("b","bb");



    }
}

上述结果是b aa ,可见执行属性值修改的时候,userpassword 并没有执行到,就stop了。

上面讲过来使用异常配合interrupt来停止异常,下面可以使用return加interrupt也可以实现。

public class Test160 {
        public static void main(String[] args) {
            Thread t = new Thread(new MyThread55());
            t.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t.interrupt();

        }
}
class MyThread55 implements Runnable{
  int i  = 0;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true) {
            System.out.println(i++);
            if(Thread.interrupted()) {
                return;
            }
        }
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值