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

      謝謝!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章