Java複習筆記之執行緒問題
一、執行緒的基本問題
作業系統中可以獨立執行的程式叫程序,程序有多個執行單元,這些執行單元可以叫做執行緒。
一個程序至少包括一個執行緒,執行緒也叫輕量級程序。
同作業系統呼叫程序一樣,程序裡的多個執行緒看似同時執行。其實也是由CPU輪流執行的,只不過CPU執行速度很快,故而給人同時執行的錯覺。
建立執行緒有兩種方式
1.繼承Thread類
class MyThread extends Thread{ public void run(){……};//一定要寫的方法,必須這麼寫 //必須這麼寫的原因有三條 //1.如果改變public為protected等,然而父類中的run方法還是public。規則是子類不能比父類的級別低,更改的話就違反了這條 //2.如果新增引數,則變為普通方法,不會在呼叫start()方法後執行run()方法。 //3.只認void的返回值,否則編譯時就會報錯 }
建立執行緒物件時則使用 MyThread my = new MyThread();
my.start();//start()方法用於啟動新執行緒,系統會自動呼叫run()方法。
若要為程序重新命名則可以重寫MyThread的構造方法,比如
public MyThread(String string) {
this.setName(string);
}
呼叫時使用new MyThread("name1")就行了。
2.實現Runnable介面
class MyThread implements Runnable{
public void run(){……};//Runnable中只有這一個方法,所以一定要實現
}
建立執行緒物件時,需要呼叫Thread()的建構函式才行
MyThread my = new MyThread();
Thread td = new Thread(my);
td.start();
簡化版1
Thread td = new Thread(new MyThread());
td.start()
;
簡化版2
new Thread(new MyTherad()).start();
Thread的構造方法中還可以傳入執行緒名比如new Thread(my,“執行緒名”)
兩種方法的對比。
Runnable 更適合多個執行緒處理一個資源的情況,把執行緒同程式程式碼、資料有效的分離,很好的體現了面向物件的設計思想。
Thread建立的不同執行緒擁有不同的資源。
Runnable 可以避免Java的單繼承帶來的侷限性。
獲取當前執行緒的名字可以通過Thread.currentThread().getName();
二、執行緒的同步問題
實現同步問題有兩個方法,同步程式碼塊和同步方法,關鍵字是synchronized
容易知道,同步程式碼塊的鎖是使用者自定義的任意物件。
那麼同步方法當然也有鎖,就是呼叫該方法的物件,也就是this指向的物件,可以用this獲取。因為物件對執行緒來說也具有唯一性,所以可以作為鎖。
如果同步的是靜態方法,不需要建立物件就可以呼叫,那麼靜態方法的鎖就是該方法所在類的class物件,可以用“類名.class”獲取。
同步解決了多個執行緒同時訪問共享資料的執行緒安全問題,即同一時間只能由一個執行緒訪問公共資源。
但是因為每次都要判斷鎖的狀態,所以非常消耗資源,效率低。
當兩個執行緒都需要使用對方的鎖,但又不釋放自己的鎖就會造成死鎖。
java虛擬機器沒有檢測,也沒有采用措施來處理死鎖情況,所以多執行緒程式設計是應該採取措施避免死鎖的出現。
一旦出現死鎖,整個程式即不會發生任何異常,也不會給出任何提示,只是所有執行緒都處於堵塞狀態。
三、其他注意的
1.解決執行緒之間的通訊問題的方法wait()、notify()、notifyAll()。
2.sleep()和wait()方法的區別?
sleep()方法讓出CPU但不會釋放同步鎖,等時間到了之後再執行當前執行緒
wait()在同步鎖內呼叫,釋放同步鎖,被喚醒後進入就緒狀態等待下一次獲得同步鎖
3.yield()和join()
yield()讓出控制權,進入就緒狀態使系統重新呼叫一次,不會阻塞程序。某個程序yield()之後,只有優先順序>=當前程序優先順序的才有可能被呼叫
當A執行緒中使用B.join()時,A將被阻塞,等B執行完時A才能繼續執行。
4.不同作業系統對執行緒優先順序的支援不一樣,不能很好的和Java中的執行緒優先順序一一對應,所以不能依賴優先順序。
5.對Java來說,只要還有一個前臺執行緒在執行,這個程序就不會結束,但只有後臺執行緒在執行,這個程序就會結束。
可以使用 執行緒.setDaemon(true),來使前臺執行緒轉換成後臺執行緒,而且必須在start()方法之前使用,否則報錯。
前後臺執行緒是相對的概念,新建立的執行緒預設都是前臺執行緒。
6.執行緒的5種狀態和轉換
.