java并发:线程中断

一共三个方法.

Thread.interrupt();//就是尝试中断本线程.将添加中断标志
Thread.isInterrupted();//查看本线程的中断标志,代表是否被中断.
Thread.static.interrupted();//静态方法,尝试中断本线程,但是中断标志会被清除.

 

看如下两段代码:

private void aaa() throws InterruptedException {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(Thread.currentThread().isInterrupted());//false				
				Thread.currentThread().interrupt();//尝试中断,添加中断标志
				System.out.println(Thread.currentThread().isInterrupted());//true
			}
		});
		t.start();
	}
private void bbb() throws InterruptedException {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(Thread.currentThread().isInterrupted());//false
				Thread.interrupted();//尝试中断,清空中断标志
				System.out.println(Thread.currentThread().isInterrupted());//false
			}
		});
		t.start();
	}

 可以看到他们的区别.

但是一个新的问题产生了.不是中断了吗?为什么后面的打印还可以执行?

 

好吧.这个得需要看文档.

文档上说了该中断方法会自上而下判断,如果符合条件,则执行该措施,且不向下穿透..

1.如果是其他线程调用该线程的中断,将执行checkAccess()方法,这可能会引起SecurityException.如果是线程本身调用自身的中断则没问题.

2.如果此时线程被wait(),join(),sleep()阻塞,那么将会抛出异常InterruptedException.中断状态清除.但LockSupport.part()没有说.

3.如果此时线程在IO中被阻塞,那么流通道将关闭,将抛出 java.nio.channels.ClosedByInterruptException.设置为中断状态.

4.如果此时线程在java.nio.channels.Selector中阻塞,那么线程将结果立即返回.设置为中断状态.

5.如果以上条件都不成立,则设置为中断状态.

而我们上面的举例貌似只有第五条符合,也就是只是设置为中断状态,其他都不会做.

我们再来看一个例子:这个例子就会符合上面第二条.抛出异常.状态清除.

其实抛出异常是终止线程的一个不错的方法.但要记得清理资源.更要注意异常会释放锁

private void sleep() throws InterruptedException {
		Thread t = new Thread(new Runnable() {	
			@Override
			public void run() {
                
				System.out.println(Thread.currentThread().isInterrupted());//此时还主线程在sleep还未执行中断,false
				try {
					Thread.currentThread().sleep(20000);//在这里被中断,抛异常
					System.out.println(Thread.currentThread().isInterrupted());//上句抛异常,这里就不会执行了.
				} catch (InterruptedException e) {
                    
					System.out.println(Thread.currentThread().isInterrupted());//中断标志被清除,false
					e.printStackTrace();
				}
				
			}
		});
		t.start();
		Thread.sleep(1000);
		t.interrupt();
	}

再来个例子,看下io阻塞的情况,实际上这玩意跟上面说的第三个规则根本不一样

private void read() throws InterruptedException {
		Runnable runnable = new Runnable() {	
			@Override
			public void run() {
				try {
					System.in.read();
				} catch (IOException e) {
					
					e.printStackTrace();
				}
				
			}
		};
		Thread t = new Thread(runnable);
		t.start();
		Thread.sleep(1000);
		t.interrupt();//完全没有用,该被阻塞的还是被阻塞,根本不抛异常.
	}

书中好像说了阻塞流和synchronized这俩根本不会受到interrupt()的影响;

 

还有一个疑问.以上5个规则,一般都是命中第五个,可说第五个只是设置了中断状态,有什么意义呢?

其实可以这样用.

private void ccc() throws InterruptedException {
		Runnable runnable = new Runnable() {	
			@Override
			public synchronized void run() {
				while(true){
					if (Thread.currentThread().isInterrupted()){
						//如果设置为中断,结束执行
						return;
					}
					//业务代码
				}
			}
		};
		Thread t = new Thread(runnable);
		t.start();
		Thread.sleep(3000);
		t.interrupt();//命令线程中断执行
	}

 

你可能感兴趣的:(【java基础】并发)