关于线程打断的一些事

1、线程打断相关的方法
* 所谓的打断并非是中断线程,而是设置线程的标识位,将默认false设置为true
* interrupt() 设置标识位
* isInterrupted() 查询标识位
* static interrupted() 查询当前线程标识位,并重置为false

example1

	@Test
    public void function1() throws InterruptedException {
        Thread t1 = new Thread(()->{
            for(;;){
                if (Thread.currentThread().isInterrupted()){
                    System.out.println("t1 被修改了标识位");
                    System.out.println(Thread.currentThread().isInterrupted());
                    Thread.interrupted();
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            }
        });
        t1.start();
        TimeUnit.SECONDS.sleep(2);
        t1.interrupt();
    }

console log

t1 被修改了标识位
true
false

2、interrupt() 与sleep()、wait()、join()
example2

@Test
public void function2(){
    Thread t2 = new Thread(()->{
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            System.out.println("睡眠中的t2线程,被设置标识位,即调用interrupt()方法触发InterruptedException异常");
            //获取当前线程的标识位,依旧为false,原因调用interrupt()方法后成功设置为true,但是由于触发异常,java机制又将其恢复为默认值false
            System.out.println(Thread.currentThread().isInterrupted());
        }
    });
    t2.start();
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    t2.interrupt();
}

console log

睡眠中的t2线程,被设置标识位,即调用interrupt()方法触发InterruptedException异常
false

3、interrupt()与wait()
example

	@Test
    public void function3(){
        final Object o = new Object();
        Thread t3 = new Thread(()->{
            synchronized (o){
                try {
                    o.wait();
                } catch (InterruptedException e) {
//                    e.printStackTrace();
                    System.out.println("等待状态下的t3线程被设置标识位,触发InterruptedException异常");
                    //同样线程标识位被java机制恢复为默认值false
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            }
        });
        t3.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t3.interrupt();
    }

console log

等待状态下的t3线程被设置标识位,触发InterruptedException异常
false

4、 interrupt()与synchronized
* interrupt()给线程设置标识位,不会影响线程竞争锁,不会抛出InterruptedException异常
* 线程t4先持有锁,睡10秒后释放锁,t4持有锁期间,虽然线程t5被设置了标识位,t4执行完t5依旧可以正常获得锁并执行
example

	@Test
    public void function4(){
        final Object o = new Object();

        Thread t4 = new Thread(()->{
            synchronized (o){
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t4.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t5 = new Thread(()->{
            synchronized (o){

            }
            System.out.println("t5 end");
        });
        t5.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t5.interrupt();
    }

console log

t5 end

5、interrupt()与JUC下的LOCK
* 如果采用reentrantLock.lock()争抢锁的方式,interrupt()不会影响线程竞争JUC下的LOCK
example

  	@Test
    public void function5(){
        final ReentrantLock reentrantLock = new ReentrantLock();

        Thread t6 = new Thread(()->{
            reentrantLock.lock();
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
            System.out.println("t6 end");
        });
        t6.start();
        //主线程睡1秒
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t7 = new Thread(()->{
            reentrantLock.lock();
            try {

            } finally {
                reentrantLock.unlock();
            }
            System.out.println("t7 end");
        });
        t7.start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t7.interrupt();
    }

6、interrupt()与JUC下的LOCK
* 如果采用reentrantLock.lockInterruptibly()争抢锁的方式,interrupt()会影响线程竞争JUC下的LOCK
example

    @Test
    public void function6(){
        final ReentrantLock reentrantLock = new ReentrantLock();

        Thread t8 = new Thread(()->{
            reentrantLock.lock();
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
            System.out.println("t8 end");
        });
        t8.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Thread t9 = new Thread(()->{
            System.out.println("t9 start");
            try {
                reentrantLock.lockInterruptibly();
            } catch (InterruptedException e) {
//                调用interrupt()方法后,会抛异常,catch块中决定是否继续争抢锁,逻辑自己控制
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
            System.out.println("t9 end");
        });
        t9.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t9.interrupt();
    }

注意,尽量不要用Junit单元测试模拟演示线程相关的程序,可能会演示不出预计的效果,原因是junit测试时@test方法执行完就会终止所有用户线程,尽量用main方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值