1. 程式人生 > >Thread原始碼-start及stop方法

Thread原始碼-start及stop方法

環境:jdk1.8

start方法原始碼如下:

/**
 * 同步方法:啟動執行緒
 */
public synchronized void start()
{
	//判斷執行緒狀態是否處於"NEW",0表示"NEW",如果不是則丟擲異常
	if (threadStatus != 0)
		throw new IllegalThreadStateException();

	//新增到執行緒組中
	group.add(this);

	//定義臨時變數用於記錄執行緒啟動狀態
	boolean started = false;
	try
	{
		//呼叫本地方法,啟動物理執行緒
		start0();
		//執行緒啟動成功
		started = true;
	} 
	finally
	{
		try
		{
			if (!started)
			{
				//執行緒啟動失敗,則將失敗執行緒從執行緒組中清掉
				group.threadStartFailed(this);
			}
		} 
		catch (Throwable ignore)
		{
			/*
			 * do nothing. If start0 threw a Throwable then it will be passed up the call
			 * stack
			 */
			//不做處理,當呼叫本地start0方法時,丟擲Throwable異常,則會自動跳出呼叫棧
		}
	}
}
執行緒啟動:1.start方法被sychronized修飾,是同步方法,即同一時刻只能有一個執行緒可以進入方法2.start方法中判斷了執行緒狀態,如果不是"NEW"狀態,則丟擲IllegalThreadStateException執行時異常,所以多次排程該方法,會出現該異常3.執行緒的啟動實際是由本地方法start0控制,底層啟動物理執行緒,並且底層丟擲任何異常,該方法也不會做任何處理4.呼叫start正常啟動起一個執行緒後,執行緒獲取到cpu時間片,jvm會回撥Thread的run方法stop方法原始碼如下:
/**
 * 非同步方法:停止執行緒,使用@Deprecated進行修飾,說明該方法已被廢棄
 */
@Deprecated
public final void stop()
{
    SecurityManager security = System.getSecurityManager();
    //許可權檢查:是否擁有停止執行緒的許可權
    if (security != null) 
    {
        checkAccess();
        if (this != Thread.currentThread()) 
        {
            security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
        }
    }

    if (threadStatus != 0) 
    {
    	//恢復暫停的執行緒
        resume(); 
    }

    // The VM can handle all thread states
    //交由虛擬機器處理執行緒死亡狀態
    stop0(new ThreadDeath());
}
執行緒停止:1.stop方法目前已被廢棄,原因是:stop會強制停止正在執行的執行緒,這可能會極大破壞資料的完整性,物件狀態也可能難於預測,執行緒處於不安全狀態以一個例子來證明執行stop可能導致執行緒不安全:程式碼如下:
public static void main(String[] args)
{
	Thread t = new Thread(new Runnable()
	{
		@Override
		public void run()
		{
			System.out.println("休息前..");
			//休息五秒
			try
			{
				TimeUnit.SECONDS.sleep(5);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			System.out.println("休息後..");
		}
	});
	
	t.start();
	try
	{
		TimeUnit.SECONDS.sleep(1);
	} 
	catch (InterruptedException e)
	{
		e.printStackTrace();
	}
	
	t.stop();
}
列印如下:
休息前..
由上可見:呼叫stop方法,可能導致執行緒中某些邏輯無法執行到,達不到預期結果