线程中断

java中所有的中断,并不能真正结束和中断线程,下图中的running状态和同步锁状态的线程,中断只是改变了它们的中断标识,并没有中断线程。

这里写图片描述

官方文档解释:

1. 如果该线程阻塞的调用wait(),wait(long)或wait(long, int)该方法的Object 类,或的join(),join(long),join(long, int),sleep(long),或者sleep(long, int),这个类的方法,那么它的中断状态将被清除,它还将收到一个InterruptedException。

2. 如果此线程在I / O操作中被阻塞,InterruptibleChannel 则通道将被关闭,线程的中断状态将被设置,并且线程将接收到ClosedByInterruptException。

3. 如果此线程被阻塞,Selector 则线程的中断状态将被设置,并且它将从选择操作立即返回,可能具有非零值,就像wakeup调用了选择器的方法一样。(非阻塞式IO)

4. 如果以前的条件都不成立,则该线程的中断状态将被设置。

5. 中断不存在的线程不需要任何效果。

测试代码:

import org.junit.Test;

public class TestInterrupt {
    /**
     * 调用wait(),wait(long)或wait(long, int),
     * 或的join(),join(long),join(long, int),
     * sleep(long),sleep(long, int),
     * 那么它的中断状态将被清除,它还将收到一个InterruptedException
     */
    @Test
    public void testSleep(){
        Thread sleep = new Thread(msgRunnable(()->{
            try {
                Thread.sleep(100);
//              synchronized (this) {
//                  wait(100);
//              }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }),"sleep线程");
        sleep.start();
        interrupt(sleep);
    }

    volatile boolean flag = true;
    /**
     * 无法中断没有阻塞的线程
     */
    @Test
    public void testRunningJob(){
        Thread running = new Thread(msgRunnable(()->{while(flag) System.out.println("running");}),"running线程");
        running.start();
        interrupt(running);
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = false;
    }

    /**
     * 无法中断由同步锁阻塞的线程
     * @throws InterruptedException 
     */
    @Test
    public void testSynchronized() throws InterruptedException{
        Object o = new Object(){
            @Override
            public synchronized String toString() {
                return "object";
            }
            @Override
            public synchronized int hashCode() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return super.hashCode();
            }
        };
        //线程A先调用o的hashCode方法,对o进行加锁
        //线程synch调用o的toString方法,同步锁阻塞
        //主线程企图中断synch
        //结果当然是主线程并不能中断synch线程,只是改变了synch的中断标识

        Thread A = new Thread(o::hashCode);
        A.start();
        //暂停1毫秒保证A执行在synch前,对o进行加锁
        Thread.sleep(1);
        Thread synch = new Thread(msgRunnable(o::toString),"synch线程");
        synch.start();
        long start = System.currentTimeMillis();
        interrupt(synch);
        //等待synch执行完毕
        synch.join();
        System.out.println("synch线程中断后持续的执行时间:"+(System.currentTimeMillis()-start));
    }


    /**
     * 等待30纳秒,中断线程
     * @param thread
     */
    private void interrupt(Thread thread) {
        try {
            Thread.sleep(0,30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":正在中断wait");
        thread.interrupt();
    }


    public Runnable msgRunnable(final Runnable r){
        return ()->{
            System.out.println(Thread.currentThread().getName()+"正在执行");
            r.run();
            System.out.println(Thread.currentThread().getName()+"中断状态为:"+Thread.currentThread().isInterrupted());
            System.out.println(Thread.currentThread().getName()+"结束");
        };
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值