Java多线程 interrupt中断阻塞

interrupt()方法

 

——interrupt()方法并不是中断线程,而是中断阻塞状态,或者将线程的[中断标志位]置为true。


——对于未阻塞的线程,interrupt()只是造成[中断标志位]=true,线程本身运行状态不受影响。


——对于阻塞的线程,interrupt()会中断阻塞状态,使其转换成非阻塞状态,并清除[中断标志位]。


——造成阻塞状态的情况有:sleep()、wait()和join()。


——阻塞状态的线程被中断时,只是中断了阻塞状态,即sleep()、wait()和join(),线程本身还在继续运行。

 

实例演示

1 非阻塞线程调用interrupt()方法    只是将中断标志位设置为true 不会影响线程正常运行

public class interrupteDemo {
	private static final Logger LOGGER=Logger.getAnonymousLogger();

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LOGGER.info("interrupt()并不是中断线程 而是将线程中断标志位设置为true");
		new Thread(
				()->
				{
					Thread thread=Thread.currentThread();
					for(int i=0;i<5;i++)
					{
						LOGGER.info("线程"+thread.getName()+"i="+i+"isInterrupted="+thread.isInterrupted());;
						if(i==2)
						{
							thread.interrupt();
						}
					}
					LOGGER.info("线程"+thread.getName()+"停止运行"+"isInterrupted="+thread.isInterrupted());
				}
				
				
				).start();
		

	}

}

 2 通过interrupt()与isInterrupted()控制for循环的运行状态(非阻塞线程)  即根据中断标志位 进行控制

 

new Thread(
				()->
				{
					Thread thread=Thread.currentThread();
					for(int i=0;i<5&&!thread.isInterrupted();i++)
					{
						LOGGER.info("线程"+thread.getName()+"i="+i+"isInterrupted="+thread.isInterrupted());;
						if(i==2)
						{
							thread.interrupt();
						}
					}
					LOGGER.info("线程"+thread.getName()+"停止运行"+"isInterrupted="+thread.isInterrupted());
				}
				
				
				).start();

可以看到执行到i=2之后不在执行 

 

3  阻塞线程(sleep/wait/joni)中的while循环应用interrupt()和isInterrupted()

 

System.out.println();
		LOGGER.info("在有阻塞状态(sleep/wait/joni)的while循环中应用interrupt()和isInterrupted()");
		Thread thread2 = new Thread(() -> {
		    //如果当前线程没被中断,则一直进行
		    while (!Thread.currentThread().isInterrupted()) {
		        LOGGER.info("线程[" + Thread.currentThread().getName() + "]正在运行...");
		        try {
		            Thread.sleep(5000);
		        } catch (InterruptedException e) {
		            e.printStackTrace();
		        }
		    }
		    LOGGER.info("线程[" + Thread.currentThread().getName() + "]停止运行");
		});
		thread2.start();
	    Thread.sleep(200);
		thread2.interrupt();

创建了thread2执行run后 由于sleep睡眠5秒 进入阻塞态

而主线程调用 thread2.interrupt将修改thread2的中断位 

使得还在5秒钟睡眠时间内的线程被打断 抛出异常

但是程序还是会继续运行

 

由此可以发现这种方式 并不能跳出循环 不是想要的结果

 

解决方案: 将catch块外移动 

 

Thread thread2 = new Thread(() -> {
		    //如果当前线程没被中断,则一直进行
			try {
		    while (!Thread.currentThread().isInterrupted()) {
		        LOGGER.info("线程[" + Thread.currentThread().getName() + "]正在运行...");
		        
		            Thread.sleep(5000);
		        } 
		    }catch (InterruptedException e) {
		    	
		    	 LOGGER.info("线程[" + Thread.currentThread().getName() + "]停止运行");
	          
	        }
		   
		});
		thread2.start();
	    Thread.sleep(200);
		thread2.interrupt();

可以看到成功的在调用interrupt之后结束循环

由此可见对阻塞线程的控制一般方法

//在线程定义类中
@Override
public void run(){
    try{
        //阻塞代码:sleep、join和wait
    }catch(InterruptedException e){
        //注释掉e.printStackTrace();
        //添加其他业务代码
    }
}

//在线程使用时
thread.interrupt();

 


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值