【Java基础总结】多线程
?1. 實(shí)現(xiàn)多線程的兩種方式
1 //第一種:繼承Thread類,重寫run()方法 2 class ThreadTest1 extends Thread{ 3 public void run(){ 4 String threadName = Thread.currentThread().getName(); 5 for(int i=0;i<10;i++){ 6 System.out.println("ThreadTest1 "+threadName+" running ... "+i); 7 } 8 } 9 } 10 11 //第二種:實(shí)現(xiàn)Runnable接口,重寫run()方法 12 class ThreadTest2 implements Runnable{ 13 public void run(){ 14 String threadName = Thread.currentThread().getName(); 15 for(int i=0;i<10;i++){ 16 System.out.println("ThreadTest2 "+threadName+" running ... "+i); 17 } 18 } 19 }實(shí)現(xiàn)方式不同,使用方式也不同
public class Demo1{ public static void main(String[] args){ThreadTest1 t1 = new ThreadTest1();ThreadTest1 t2 = new ThreadTest1();Thread t3 = new Thread(new ThreadTest2());Thread t4 = new Thread(new ThreadTest2());t1.start();t2.start();t3.start();t4.start();} }運(yùn)行結(jié)果大致如下:
ThreadTest1 Thread-0 running ... 0 ThreadTest2 Thread-3 running ... 0 ThreadTest2 Thread-2 running ... 0 ThreadTest1 Thread-1 running ... 0 ThreadTest2 Thread-2 running ... 1 ThreadTest2 Thread-3 running ... 1 ThreadTest1 Thread-0 running ... 1 ThreadTest2 Thread-3 running ... 2 ThreadTest2 Thread-2 running ... 2 ThreadTest1 Thread-1 running ... 1 ThreadTest2 Thread-2 running ... 3 ThreadTest2 Thread-3 running ... 3 ThreadTest1 Thread-0 running ... 2 ThreadTest2 Thread-3 running ... 4 ThreadTest2 Thread-2 running ... 4 ThreadTest1 Thread-1 running ... 2 ThreadTest2 Thread-2 running ... 5 ThreadTest2 Thread-3 running ... 5 ThreadTest1 Thread-0 running ... 3 ThreadTest2 Thread-3 running ... 6 ThreadTest2 Thread-2 running ... 6 ThreadTest1 Thread-1 running ... 3 ThreadTest2 Thread-2 running ... 7 ThreadTest2 Thread-3 running ... 7 ThreadTest2 Thread-3 running ... 8 ThreadTest2 Thread-3 running ... 9 ThreadTest1 Thread-0 running ... 4 ThreadTest1 Thread-0 running ... 5 ThreadTest2 Thread-2 running ... 8 ThreadTest2 Thread-2 running ... 9 ThreadTest1 Thread-1 running ... 4 ThreadTest1 Thread-0 running ... 6 ThreadTest1 Thread-0 running ... 7 ThreadTest1 Thread-0 running ... 8 ThreadTest1 Thread-1 running ... 5 ThreadTest1 Thread-0 running ... 9 ThreadTest1 Thread-1 running ... 6 ThreadTest1 Thread-1 running ... 7 ThreadTest1 Thread-1 running ... 8 ThreadTest1 Thread-1 running ... 9 View Code?
2. 線程共享資源
建議使用?實(shí)現(xiàn)Runnable接口,重寫run方法?的方式來實(shí)現(xiàn)多線程,它有如下優(yōu)點(diǎn):
1. 線程和代碼分離,多線程間可以共享資源
2. 避免了單繼承帶來的局限性
3.?多線程之間可以共享資源
tip
Thread.currentThread().getName() 獲得當(dāng)前線程的名稱 threadObj.setName() 設(shè)置線程名稱?
案例:售票
class ThreadTest4 implements Runnable{private int ticket=20;public void run(){String threadName = Thread.currentThread().getName();while(ticket>0){System.out.println("ThreadTest4 "+threadName+" 售出 "+ticket+" 號(hào)票");ticket--;}} }使用情況1:
(new Thread(new ThreadTest4(), "窗口a")).start();(new Thread(new ThreadTest4(), "窗口b")).start();(new Thread(new ThreadTest4(), "窗口c")).start();(new Thread(new ThreadTest4(), "窗口d")).start();運(yùn)行情況說明A、B、C、D四個(gè)窗口也沒用共享count這個(gè)資源
主線程名稱:main ThreadTest4 窗口a 售出 20 號(hào)票 ThreadTest4 窗口a 售出 19 號(hào)票 ThreadTest4 窗口b 售出 20 號(hào)票 ThreadTest4 窗口b 售出 19 號(hào)票 ThreadTest4 窗口b 售出 18 號(hào)票 ThreadTest4 窗口b 售出 17 號(hào)票 ThreadTest4 窗口b 售出 16 號(hào)票 ThreadTest4 窗口b 售出 15 號(hào)票 ThreadTest4 窗口a 售出 18 號(hào)票 ThreadTest4 窗口b 售出 14 號(hào)票 ThreadTest4 窗口d 售出 20 號(hào)票 ThreadTest4 窗口c 售出 20 號(hào)票 ThreadTest4 窗口d 售出 19 號(hào)票 ThreadTest4 窗口b 售出 13 號(hào)票 ThreadTest4 窗口a 售出 17 號(hào)票 ThreadTest4 窗口b 售出 12 號(hào)票 ThreadTest4 窗口d 售出 18 號(hào)票 ThreadTest4 窗口c 售出 19 號(hào)票 ThreadTest4 窗口d 售出 17 號(hào)票 ThreadTest4 窗口b 售出 11 號(hào)票 ThreadTest4 窗口a 售出 16 號(hào)票 ThreadTest4 窗口b 售出 10 號(hào)票 ThreadTest4 窗口d 售出 16 號(hào)票 ThreadTest4 窗口c 售出 18 號(hào)票 ThreadTest4 窗口d 售出 15 號(hào)票 ThreadTest4 窗口b 售出 9 號(hào)票 ThreadTest4 窗口a 售出 15 號(hào)票 ThreadTest4 窗口b 售出 8 號(hào)票 ThreadTest4 窗口d 售出 14 號(hào)票 ThreadTest4 窗口c 售出 17 號(hào)票 ThreadTest4 窗口d 售出 13 號(hào)票 ThreadTest4 窗口b 售出 7 號(hào)票 ThreadTest4 窗口a 售出 14 號(hào)票 ThreadTest4 窗口b 售出 6 號(hào)票 ThreadTest4 窗口d 售出 12 號(hào)票 ThreadTest4 窗口c 售出 16 號(hào)票 ThreadTest4 窗口d 售出 11 號(hào)票 ThreadTest4 窗口b 售出 5 號(hào)票 ThreadTest4 窗口a 售出 13 號(hào)票 ThreadTest4 窗口b 售出 4 號(hào)票 ThreadTest4 窗口d 售出 10 號(hào)票 ThreadTest4 窗口c 售出 15 號(hào)票 ThreadTest4 窗口d 售出 9 號(hào)票 ThreadTest4 窗口b 售出 3 號(hào)票 ThreadTest4 窗口a 售出 12 號(hào)票 ThreadTest4 窗口b 售出 2 號(hào)票 ThreadTest4 窗口d 售出 8 號(hào)票 ThreadTest4 窗口c 售出 14 號(hào)票 ThreadTest4 窗口d 售出 7 號(hào)票 ThreadTest4 窗口b 售出 1 號(hào)票 ThreadTest4 窗口a 售出 11 號(hào)票 ThreadTest4 窗口a 售出 10 號(hào)票 ThreadTest4 窗口d 售出 6 號(hào)票 ThreadTest4 窗口c 售出 13 號(hào)票 ThreadTest4 窗口d 售出 5 號(hào)票 ThreadTest4 窗口a 售出 9 號(hào)票 ThreadTest4 窗口d 售出 4 號(hào)票 ThreadTest4 窗口c 售出 12 號(hào)票 ThreadTest4 窗口d 售出 3 號(hào)票 ThreadTest4 窗口a 售出 8 號(hào)票 ThreadTest4 窗口d 售出 2 號(hào)票 ThreadTest4 窗口c 售出 11 號(hào)票 ThreadTest4 窗口d 售出 1 號(hào)票 ThreadTest4 窗口a 售出 7 號(hào)票 ThreadTest4 窗口c 售出 10 號(hào)票 ThreadTest4 窗口a 售出 6 號(hào)票 ThreadTest4 窗口a 售出 5 號(hào)票 ThreadTest4 窗口a 售出 4 號(hào)票 ThreadTest4 窗口a 售出 3 號(hào)票 ThreadTest4 窗口a 售出 2 號(hào)票 ThreadTest4 窗口a 售出 1 號(hào)票 ThreadTest4 窗口c 售出 9 號(hào)票 ThreadTest4 窗口c 售出 8 號(hào)票 ThreadTest4 窗口c 售出 7 號(hào)票 ThreadTest4 窗口c 售出 6 號(hào)票 ThreadTest4 窗口c 售出 5 號(hào)票 ThreadTest4 窗口c 售出 4 號(hào)票 ThreadTest4 窗口c 售出 3 號(hào)票 ThreadTest4 窗口c 售出 2 號(hào)票 ThreadTest4 窗口c 售出 1 號(hào)票 View Code使用情況2:
ThreadTest4 t2 = new ThreadTest4();(new Thread(t2,"窗口1")).start();(new Thread(t2,"窗口2")).start();(new Thread(t2,"窗口3")).start();(new Thread(t2,"窗口4")).start();運(yùn)行情況說明A、B、C、D四個(gè)窗口共享count這個(gè)資源(但發(fā)生了訪問沖突)
主線程名稱:main ThreadTest4 窗口1 售出 20 號(hào)票 ThreadTest4 窗口2 售出 20 號(hào)票 ThreadTest4 窗口2 售出 19 號(hào)票 ThreadTest4 窗口2 售出 18 號(hào)票 ThreadTest4 窗口2 售出 17 號(hào)票 ThreadTest4 窗口2 售出 16 號(hào)票 ThreadTest4 窗口2 售出 15 號(hào)票 ThreadTest4 窗口2 售出 14 號(hào)票 ThreadTest4 窗口2 售出 13 號(hào)票 ThreadTest4 窗口2 售出 12 號(hào)票 ThreadTest4 窗口2 售出 11 號(hào)票 ThreadTest4 窗口2 售出 10 號(hào)票 ThreadTest4 窗口2 售出 9 號(hào)票 ThreadTest4 窗口2 售出 8 號(hào)票 ThreadTest4 窗口2 售出 7 號(hào)票 ThreadTest4 窗口3 售出 7 號(hào)票 ThreadTest4 窗口1 售出 5 號(hào)票 ThreadTest4 窗口2 售出 6 號(hào)票 ThreadTest4 窗口1 售出 3 號(hào)票 ThreadTest4 窗口4 售出 4 號(hào)票 ThreadTest4 窗口3 售出 4 號(hào)票 ThreadTest4 窗口1 售出 1 號(hào)票 ThreadTest4 窗口2 售出 2 號(hào)票 View Code?
3. 線程同步
? ?多線程中涉及到共享數(shù)據(jù)時(shí),會(huì)出現(xiàn)線程安全問題。就上面的售票案例來說,若沒有加?synchronized?關(guān)鍵字,在多個(gè)線程同時(shí)使用ticket這個(gè)共享數(shù)據(jù)時(shí),會(huì)出現(xiàn)同一個(gè)ticket被使用兩次這樣的看似不可能的情況。另外還有一種情況,事實(shí)上ticket這個(gè)共享數(shù)據(jù)是類ThreadTest4對(duì)象t2中的變量,所以若是在主線程中添加t2.run();語句的話,也是會(huì)發(fā)生線程安全問題的。
? ?在Java里面,同步鎖的概念就是這樣的。任何一個(gè)Object Reference都可以作為同步鎖。我們可以把Object Reference理解為對(duì)象在內(nèi)存分配系統(tǒng)中的內(nèi)存地址。
1 class ThreadTest5 implements Runnable{ 2 private int ticket=20; 3 public void run(){ 4 while(ticket>0){ 5 String threadName = Thread.currentThread().getName(); 6 //同步代碼塊(越小越好) 7 synchronized(this){ 8 if(ticket>0){ 9 System.out.println(threadName + " sales ticket "+ticket); 10 ticket--; 11 } 12 } 13 } 14 } 15 } 16 17 public class Demo3{ 18 public static void main(String[] args){ 19 ThreadTest5 t = new ThreadTest5(); 20 (new Thread(t, "窗口A")).start(); 21 (new Thread(t, "窗口B")).start(); 22 (new Thread(t, "窗口C")).start(); 23 (new Thread(t, "窗口D")).start(); 24 } 25 }運(yùn)行結(jié)果
窗口A sales ticket 20 窗口A sales ticket 19 窗口A sales ticket 18 窗口A sales ticket 17 窗口A sales ticket 16 窗口A sales ticket 15 窗口A sales ticket 14 窗口A sales ticket 13 窗口A sales ticket 12 窗口A sales ticket 11 窗口A sales ticket 10 窗口D sales ticket 9 窗口D sales ticket 8 窗口D sales ticket 7 窗口D sales ticket 6 窗口D sales ticket 5 窗口D sales ticket 4 窗口D sales ticket 3 窗口C sales ticket 2 窗口B sales ticket 1 View Code(1)同步代碼塊
synchronized(類或?qū)ο?{//需要同步的代碼段 }(2)同步函數(shù)
(非static的情況)
public synchronized void fun(){//代碼段 }等價(jià)于(調(diào)用此同步函數(shù)的對(duì)象作為此同步函數(shù)的同步鎖)
public void fun() {synchronized(this) {//代碼段 } }(static的情況)
public static synchronized void fun() {//代碼段 }靜態(tài)變量或靜態(tài)方法加載到內(nèi)存中時(shí),內(nèi)存中沒有本類對(duì)象,但一定有了該類對(duì)應(yīng)的字節(jié)碼文件(類名.class),該對(duì)象的類型是class。靜態(tài)同步函數(shù)使用的同步鎖是所在類的字節(jié)碼文件。
?
線程同步的前提:
1)2個(gè)或2個(gè)以上的線程
2)使用同一把鎖
保證同步中只有一個(gè)線程在運(yùn)行。
好處:解決線程安全問題
弊端:多個(gè)線程需要判斷鎖,消耗資源
?
4. 線程通信
經(jīng)典的生產(chǎn)者和消費(fèi)者問題
假設(shè)倉庫中只能存放一件產(chǎn)品,生產(chǎn)者將生產(chǎn)出來的產(chǎn)品放入倉庫,消費(fèi)者將倉庫中的產(chǎn)品取走消費(fèi)。如果倉庫中沒有產(chǎn)品,則生產(chǎn)者可以將產(chǎn)品放入倉庫,否則停止生產(chǎn)并等待,直到倉庫中的產(chǎn)品被消費(fèi)者取走為止。如果倉庫中放有產(chǎn)品,則消費(fèi)者可以將產(chǎn)品取走消費(fèi),否則停止消費(fèi)并等待,直到倉庫中再次放入產(chǎn)品為止。顯然,這是一個(gè)同步問題,生產(chǎn)者和消費(fèi)者共享同一資源,并且,生產(chǎn)者和消費(fèi)者之間彼此依賴,互為條件向前推進(jìn)
4.1 synchronized和wait、notify、notifyAll
?wait()?使得當(dāng)前線程必須要等待,并釋放對(duì)鎖的擁有權(quán),等到另外一個(gè)線程調(diào)用notify()或者notifyAll()方法
?notify()?會(huì)喚醒一個(gè)等待當(dāng)前對(duì)象的鎖的線程
?notifyAll()?喚醒所有一個(gè)等待當(dāng)前對(duì)象的鎖的線程
一個(gè)小比較
當(dāng)線程調(diào)用了wait()方法時(shí),它會(huì)釋放掉對(duì)象的鎖。
另一個(gè)會(huì)導(dǎo)致線程暫停的方法:Thread.sleep(millisecond),它會(huì)導(dǎo)致線程睡眠指定的毫秒數(shù),但線程在睡眠的過程中是不會(huì)釋放掉對(duì)象的鎖的。
其中一種運(yùn)行結(jié)果:
1 [消費(fèi)者1]倉庫沒有饅頭!! 2 [消費(fèi)者2]倉庫沒有饅頭!! 3 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[1] 個(gè) 4 [消費(fèi)者2]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[0] 個(gè) 5 [消費(fèi)者1]倉庫沒有饅頭!! 6 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[1] 個(gè) 7 [消費(fèi)者1]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[0] 個(gè) 8 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[1] 個(gè) 9 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[2] 個(gè) 10 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[3] 個(gè) 11 [消費(fèi)者2]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[2] 個(gè) 12 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[3] 個(gè) 13 [消費(fèi)者1]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[2] 個(gè) 14 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[3] 個(gè) 15 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[4] 個(gè) 16 [消費(fèi)者2]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[3] 個(gè) 17 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[4] 個(gè) 18 [消費(fèi)者1]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[3] 個(gè) 19 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[4] 個(gè) 20 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[5] 個(gè) 21 [生產(chǎn)者B]倉庫已達(dá)到最大容量 5 個(gè) !! 22 [消費(fèi)者2]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[4] 個(gè) 23 [生產(chǎn)者B]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[5] 個(gè) 24 [生產(chǎn)者A]倉庫已達(dá)到最大容量 5 個(gè) !! 25 [消費(fèi)者1]倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[4] 個(gè) 26 [生產(chǎn)者A]倉庫增加了一個(gè)饅頭,現(xiàn)有饅頭[5] 個(gè) 27 [生產(chǎn)者B]倉庫已達(dá)到最大容量 5 個(gè) !! 28 [生產(chǎn)者A]倉庫已達(dá)到最大容量 5 個(gè) !!(運(yùn)行結(jié)果分析)
1)線程“消費(fèi)者1”調(diào)用repositoy.fetch()方法去倉庫取饅頭。進(jìn)入synchronized塊,剛一執(zhí)行while語句,結(jié)果 this.count<1 為真,直接就wait()進(jìn)入等待隊(duì)列,最后釋放了鎖 (就緒隊(duì)列[消費(fèi)者2,生產(chǎn)者A,生產(chǎn)者B],等待隊(duì)列[消費(fèi)者1]) 2)線程“消費(fèi)者2”同“消費(fèi)者1”的遭遇是相同的(對(duì)此,我們深表同情) (就緒隊(duì)列[生產(chǎn)者A,生產(chǎn)者B], 等待隊(duì)列[消費(fèi)者1,消費(fèi)者2]) 3)線程“生產(chǎn)者A”生產(chǎn)完商品后,調(diào)用repository.store()方法把商品存到了倉庫中。在store方法里,使用notifyAll方法喚醒了所有在沉睡wait的線程,最后釋放了鎖 (就緒隊(duì)列[生產(chǎn)者A,生產(chǎn)者B,消費(fèi)者1,消費(fèi)者2],等待隊(duì)列[]) 4)線程“消費(fèi)者2”從上次wait的地方開始執(zhí)行(從哪里跌倒,就從哪里爬起來)。同樣是while語句,但這次 this.count<1 不為真了,于是乎順利脫坑,接著執(zhí)行 this.count--,把倉庫僅有的一個(gè)饅頭給拿走了,走之前還不忘大喊一句“倉庫減少了一個(gè)饅頭,現(xiàn)有饅頭[0] 個(gè)”。同樣是notifyAll方法喚醒所有沉睡wait的線程,釋放鎖 (就緒隊(duì)列[生產(chǎn)者A,生產(chǎn)者B,消費(fèi)者1,消費(fèi)者2],等待隊(duì)列[]) 5)線程“消費(fèi)者1”辛辛苦苦搶到了鎖,終于能執(zhí)行syschronized塊代碼了。和“消費(fèi)者2”一樣,也是從上次wait的地方接著執(zhí)行,也是while語句,但不同的是 this.count<1 為真,線程“生產(chǎn)者A”生產(chǎn)存放到倉庫的僅有的一個(gè)饅頭被“消費(fèi)者2”給吃了,可以想象此時(shí)的“消費(fèi)者1”心里是萬念俱灰的。啥也別說了,接著沉睡wait吧。(釋放了鎖) (就緒隊(duì)列[生產(chǎn)者A,生產(chǎn)者B,消費(fèi)者2],等待隊(duì)列[消費(fèi)者1])**** 在接下來的幾十個(gè)回合中,時(shí)而生產(chǎn)者線程奪得倉庫鎖,稱霸武林,時(shí)而消費(fèi)者線程奪得,笑傲江湖,倉庫商品也是時(shí)增時(shí)減,但總體上還是生產(chǎn)者線程搶到的次數(shù)多,因?yàn)樯a(chǎn)者夠快,當(dāng)消費(fèi)者還在花2秒鐘費(fèi)勁的消化時(shí),生產(chǎn)者早就1秒生產(chǎn)完畢,參與倉庫鎖的再次爭(zhēng)奪了,可見“天下武功,唯快不破” *****“倉庫里沒有饅頭為什么不通知我?”,線程“消費(fèi)者2”不滿“消費(fèi)者1”對(duì)倉庫情況的隱瞞不報(bào),“你要是早告訴我,我也就不用爭(zhēng)搶倉庫鎖,搶到了也沒用,里面根本就沒有饅頭,去了也是wait”。(第1、2步) “你還有臉說我,你把生產(chǎn)者A生產(chǎn)存放在倉庫僅有的一個(gè)饅頭吃了,你明知道倉庫再也沒有饅頭了,也不告訴我,還讓我傻了吧唧搶到倉庫鎖,去了也白搭”。“消費(fèi)者1”反駁道,它同樣也很委屈。(第4、5步) “管我什么事,搶倉庫鎖的有不只你一個(gè),我也去搶了,白費(fèi)了勁,還沒搶到....”,線程“消費(fèi)者2”道。“要是倉庫沒有饅頭的時(shí)侯,只喚醒那幫生產(chǎn)者就好了”,線程“消費(fèi)者1”和“消費(fèi)者2”異口同聲的說道。
處理線程通信必須遵循一種原則:對(duì)于生產(chǎn)者,在生產(chǎn)者沒有生產(chǎn)之前,要通知消費(fèi)者等待;在生產(chǎn)者生產(chǎn)之后,馬上又通知消費(fèi)者消費(fèi);對(duì)于消費(fèi)者,在消費(fèi)者消費(fèi)之后,要通知生產(chǎn)者已經(jīng)消費(fèi)結(jié)束,需要繼續(xù)生產(chǎn)新的產(chǎn)品以供消費(fèi)。
4.2 Lock和Condition
Lock 實(shí)現(xiàn)提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。此實(shí)現(xiàn)允許更靈活的結(jié)構(gòu),可以具有差別很大的屬性,可以支持多個(gè)相關(guān)的 Condition 對(duì)象。
Condition 將 Object 監(jiān)視器方法(wait、notify 和 notifyAll)分解成截然不同的對(duì)象,以便通過將這些對(duì)象與任意 Lock 實(shí)現(xiàn)組合使用,為每個(gè)對(duì)象提供多個(gè)等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和語句的使用,Condition 替代了 Object 監(jiān)視器方法的使用
?
5. 停止線程的方法
interrupt() //停止線程 isInterrupt() //判斷線程是否停止6. 守護(hù)線程和join方法
守護(hù)線程是為其他線程提供便利服務(wù)的,當(dāng)全部的用戶線程結(jié)束后,守護(hù)線程才會(huì)隨JVM結(jié)束工作。?thread.setDaemon(true);?
public static void main(String[] args){ Thread t3 = new Thread(test2, "線程t3");t3.start();t3.join(); //主線程就此陷入等待,直到t3線程結(jié)束。 }7. 線程優(yōu)先級(jí)和yield方法
線程的優(yōu)先級(jí)從低到高:1-10,優(yōu)先級(jí)高的的優(yōu)先執(zhí)行,每個(gè)新線程都繼承了父線程的優(yōu)先級(jí),常量:Thread.MIN_PRIORITY 值為1,Thread.MAX_PRIORITY 值為10,Thread.NORM_PRIORITY 值為5
void setPriority(priority) //設(shè)置線程優(yōu)先級(jí) int getPriority() //獲取線程優(yōu)先級(jí)?yield()?線程從執(zhí)行狀態(tài)變成就緒狀態(tài)。
?
轉(zhuǎn)載于:https://www.cnblogs.com/lhat/p/6819170.html
總結(jié)
以上是生活随笔為你收集整理的【Java基础总结】多线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到蟒蛇是什么意思
- 下一篇: Java之杨辉三角的实现