Java线程_线程中断(interrupt)相关

      今天聊些线程中断相关的内容,因为笔者在看书之前是不知道了解这些东西的,所以这里做下笔记。可能还有其他和笔者一样的朋友,可以参考一下。

      和线程中断的有3个方法,分别是:interrupt()、interrupted()、isInterrupted()。区别在于:interrupt用于设置目标线程对象的一个中断标志;interrupted()是一个静态方法,用来返回当前目标线程的标志值,而isInterrupted()则是动态的,它必须在一个线程对象上执行。

       有一点很重要的是线程在wait()、sleep()、join()中被interrupt()会抛出异常,但是又不会置将中断标记置为true,而在非阻塞状态中中断标记会被置为true,但却又不会报异常。很有意思吧,这意味着如果线程正处于非阻塞状态处理事务,则对线程调用interrupt后,线程会继续当前事务,只是线程的中断标记被设置了而已。这很重要!!

       谈谈笔者对以上现象的理解,可以这么想,如果线程处于阻塞状态(sleep,wait,join),则调用interrupt目的是让线程立刻退出阻塞状态,于是通过抛出一个异常来实现立刻中断。其实我们可以忽略这个异常,然后使线程马上往下继续运行。至于在非阻塞状态被中断,应该是出于操作完整性的考虑,即首先要保证本次操作的完整性,然后对当前任务置中断标记,使得线程在开启下次任务前根据中断标记来彻底结束线程。总结一句话,线程中断是以循环为单位,即要保持每次循环运行的完整性,中断的意思不是kill本次循环内的操作,而是阻止下次循环的开始。

        测试代码:

package com.wly.javathread.chap4;

/**
 * 测试interrupt
 * 一、在wait()、sleep()、join()中被interrupt()会抛出异常,但是又不会置interrupt标记。在其他非阻塞
 * 状态中被interrupt则会置中断标记,但却不会报异常。
        二、意味着,如果线程正处于非阻塞状态处理事务,则对线程调用interrupt后,线程会继续当前事务,只是线程的中断标
        记被设置了而已。这很重要!!
 * @author wly
 *
 */
public class TestInterrupt {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//测试线程,不断的创建MyThread,然后中断
		new Thread() {
			@Override
			public void run() {
				super.run();
				int i = 0;
				while(i < 2) {
					MyThread myThread = new MyThread();
					myThread.start();
					
					//生成随机的中断时间间隔,进行测试
					try {
						sleep((int)(Math.random() * 4000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					myThread.interrupt();
					
					if(myThread.isInterrupted()) {
						i++;
					}
				}
			}
		}.start();
	}

	static class MyThread extends Thread {

		@Override
		public void run() {
			super.run();

			while(!isInterrupted()) {
				//阻塞耗时阶段
				System.out.println("线程" + Thread.currentThread().getId() + "进入阻塞--");
				try {
					sleep(2000);
				} catch (InterruptedException e) {
					System.out.println("--线程被中断了,当前中断标记值:" + interrupted());
				}
				System.out.println("线程" + Thread.currentThread().getId() + "退出阻塞--");
				
				//非阻塞耗时阶段
				System.out.println("线程" + Thread.currentThread().getId() + "进入非阻塞--");
				for(int i=0;i<100000;i++) {
					for(int j=0;j<50000;j++) {
						j++;
					}
				}
				System.out.println("线程" + Thread.currentThread().getId() + "退出非阻塞--");
				System.out.println("线程" + Thread.currentThread().getId()
						+ "中断标记值:" + isInterrupted());
			}
		}
	}
}

      运行结果:

线程9进入阻塞--
--线程被中断了,当前中断标记值:false
线程9退出阻塞--
线程9进入非阻塞--
线程11进入阻塞--
线程9退出非阻塞--
线程9中断标记值:false
线程9进入阻塞--
线程11退出阻塞--
线程11进入非阻塞--
线程9退出阻塞--
线程9进入非阻塞--
线程11退出非阻塞--
线程11中断标记值:true
线程9退出非阻塞--
线程9中断标记值:false
线程9进入阻塞--
线程9退出阻塞--
线程9进入非阻塞--
线程9退出非阻塞--
线程9中断标记值:false
线程9进入阻塞--
线程9退出阻塞--
线程9进入非阻塞--
线程9退出非阻塞--

         从上面运行结果可以看出,在阻塞状态中断不会改变中断标记,而在非阻塞状态会改变中断标记。

      O啦~~~

      转载请保留出处:http://blog.csdn.net/u011638883/article/details/18326893

      谢谢!!

你可能感兴趣的:(Java线程_线程中断(interrupt)相关)