java se基礎-多執行緒
多執行緒
1.理解程式、程序、執行緒的概念
程式可以理解為靜態的程式碼
程序可以理解為執行中的程式
執行緒可以理解為程序的進一步細分,程式的一條執行路徑
2.如何建立java程式的執行緒(重點)
方式一:繼承Thread類
class PrintNum extends Thread{ public void run(){ //子執行緒執行的程式碼 for(inti = 1;i <= 100;i++){ if(i% 2 == 0){ System.out.println(Thread.currentThread().getName()+ ":" + i); } } } public PrintNum(String name){ super(name); } } public class TestThread { public static void main(String[] args) { Print Nump1 = new PrintNum("執行緒1"); Print Nump2 = new PrintNum("執行緒2"); p1.setPriority(Thread.MAX_PRIORITY);//10 p2.setPriority(Thread.MIN_PRIORITY);//1 p1.start(); p2.start(); } }
方式二:實現Runnable介面
class SubThread implements Runnable{ public void run(){ //子執行緒執行的程式碼 for(inti = 1;i <= 100;i++){ if(i% 2 == 0){ System.out.println(Thread.currentThread().getName()+":"+ i); } } } } public class TestThread{ publicstatic void main(String[] args){ SubThread s = new SubThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); t1.setName("執行緒1"); t2.setName("執行緒2"); t1.start(); t2.start(); } }
兩種方式的對比:聯絡:class Thread implements Runnable
比較哪個好?實現的方式較好. a.解決了單繼承的侷限性 b.如果多個執行緒有共享資料的話,建議使用實現方式.同時,共享資料所在的類可以作為Runnable介面的實現類
執行緒裡的常用方法:start() run() currentThread() getName() setName(String name) yield() join() sleep() isAlive() wait() notify() notifyAll()
3.執行緒的生命週期
4.執行緒的同步機制(重點)
前提:如果我們建立的多個執行緒,存在著共享資料,那麼就可能出現執行緒的安全問題:當其中一個執行緒操作共享資料時,還未操作完成,另外的執行緒就參與進來,導致對共享資料的操作出現問題.
解決方式:要求一個執行緒操作共享資料時,只有當其完成操作共享資料,其他執行緒才有機會執行共享資料.
方式一:同步程式碼塊:
synchronized(同步監視器){
//操作共享資料的程式碼
}
注:1.同步監視器:俗稱鎖,任何一個類的物件都可以充當鎖.要想保證執行緒的安全,必須要求所有的執行緒共用同一把鎖!
2.使用實現Runnable介面的方式建立多執行緒的話,同步程式碼塊中的鎖,可以考慮是this,如果使用繼承Thread類的方式,慎用this!
3.共享資料:多個執行緒需要共同操作的變數.明確哪部分是操作共享資料的程式碼.
方式二:同步方法:將操作共享資料的方法宣告為synchronized.
比如:publicsynchronized void show(){//操作共享資料的程式碼}
注:1.對於非靜態的方法而言,使用同步的話,預設鎖為:this,如果使用在繼承的方式實現多執行緒的話,慎用!
2.對於靜態的方法,如果使用同步,預設的鎖為:當前類本身.以前類本身.以單例的懶漢式為例. Class clazz = Singleton.class
總結:釋放鎖: wait();
不釋放鎖:sleep() yield() suspend() (過時,可能導致死鎖)
死鎖:不同的執行緒分別佔用對方需要的同步資源不放棄,都在等待對方放棄自己需要的同步資源,就形成了執行緒的死鎖.死鎖是我們在使用同步時,需要避免的問題!
5.執行緒的通訊:如下的三個方法必須使用在同步程式碼塊或同步方法中!
wait():當在同步中,執行到此方法,則此執行緒"等待",直至其他執行緒執行notity()的方法,將其喚醒,喚醒後繼續其wait()後的程式碼
notify()/notifyAll():在同步中,執行到此方法,則喚醒其他的某一個或所有的被wait的執行緒.