Java並發編程總結1——線程狀態、synchronized


 

    以下內容主要總結自《Java多線程編程核心技術》,不定時補充更新。

 

一、線程的狀態

    Java中,線程的狀態有以下6類:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED。各狀態之間的關系可用下圖表示:

 

二、常用方法介紹

1、thread.start()和thread.run()的區別

1 public static void main(String[] args) {
2         Thread t = new Thread();
3         t.start();
4         System.out.println("main end");
5     }

調用start()方法啟動線程t,t線程的狀態會從New -> Runnable,t線程和main主線程同時執行。

如果把t.start()改成t.run(),則是普通的調用方法,同步執行,System.out.println("main end")語句必須等t.run()方法執行完畢之后才能執行。

注意:t.run()方法不會改變線程t的狀態,也就是說線程沒有啟動。

 

2、object.wait()和thread.sleep()的區別

復制代碼
1 private Object obj = new Object();
2 public void testMethod() throws InterruptedException {
3     synchronized (obj) {
4         obj.wait();
5         System.out.println("testMethod end");
6     }
7 }
復制代碼

wait()方法主要用在synchronized同步方法或者同步塊中,意味着調用object.wait()之前必須先獲取鎖,調用wait()方法之后釋放鎖,線程進入waiting狀態。常見用法如上所示。如果有其他線程通過調用object.notify()或者object.notifyAll()方法時,線程必須再次獲取到obj鎖,然后才能繼續執行obj.wait()后的語句,即打印 "testMethod end"。obj.wait(timeout)方法類似,也需要先釋放鎖。

wait()方法是Object類的方法,而sleep(timeout)方法是Thread類的方法。線程調用sleep(timeout)方法,狀態從runnable -> timed_waiting,但是不釋放鎖。

 

3、interrupt()方法

    當線程調用interrupt()方法時,只是設置了線程的中斷狀態。 也就是說如果線程處於runnable或者blocked狀態的時候,調用interrupt()方法並不會終止線程。於是,我想當然的理解如果線程處於waiting或者timed_waiting狀態時,調用interrupt方法會拋出異常,從而終止線程。

    然后發現錯了。見如下代碼:

復制代碼
 1 private ReentrantLock lock = new ReentrantLock();
 2 private Condition condition = lock.newCondition();
 3 public void testMethod() {
 4     try {
 5         lock.lock();
 6         System.out.println("wait begin");
 7         condition.awaitUninterruptibly();
 8         System.out.println("wait end");
 9     } finally {
10         lock.unlock();
11     }
12 }
復制代碼

    condition.awaitUninterruptibly()方法不需要捕獲InterruptedException異常,意味着如果線程通過調用awaitUninterruptibly從而使得線程狀態為waiting,並不會因為調用interrupt()方法而中斷。實際測試,線程狀態不響應interrupt方法,只有通過condition.singal或者singalAll才能喚醒線程。

    實際測試,wait(), wait(timeout), join(), sleep(timeout), await(), await(timeout)等方法都是可以被interrupt()方法中斷的。

 

三、synchronized關鍵字

1、synchronized(object): 同步方法或者代碼塊,鎖是一個對象。

2、synchronized(this): this指的是當前對象。

3、針對靜態方法,比如synchronized public static void testMethod(),鎖是當前的Class類。

4、如果代碼拋出異常,鎖自動釋放。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM