摘要:上次是說到了多線程的創(chuàng)建和狀態(tài)樂字節(jié),接下來,我們再來接著說多線程同步和線程通信生產(chǎn)者消費(fèi)者模式。另一方面,線程通信使線程能夠等待其他線程的信號。
大家伙周末愉快,小樂又來給大家獻(xiàn)上技術(shù)大餐。上次是說到了Java多線程的創(chuàng)建和狀態(tài)|樂字節(jié),接下來,我們再來接著說Java多線程-同步:synchronized 和線程通信:生產(chǎn)者消費(fèi)者模式。
一、同步:synchronized多個線程同時訪問一個對象,可能造成非線程安全,數(shù)據(jù)可能錯誤,所謂同步:就是控制多個線程同時訪就是控制多線程操作同一個對象時,注意是同一個對象,數(shù)據(jù)的準(zhǔn)確性, 確保數(shù)據(jù)安全,但是加入同步后因?yàn)樾枰却?,所以效率相對低下?/p>
如:一個蘋果,自己一個人去咬怎么都不會出問題,但是多個人同時去咬,這個時候如果控制不好,就可能會咬到對方了。 再強(qiáng)調(diào)一下是一個蘋果。
12306 中的火車票,為什么搶到票時,需要等待,鎖定席位才付款?這就是確保一張票只能一個人去購買。
1、同步塊synchronized +塊:同步塊
synchronized (引用類型|對象|類.class) {
}
2、同步方法修飾符 synchronized 返回類型|void 方法簽名{
}
3、死鎖過多的同步容易死鎖
/** * 死鎖:容易造成死鎖 * @author Administrator * */ public class TestDeadLock { /** * @param args */ public static void main(String[] args) { Object obj1 =new Object(); Object obj2 =new Object(); new A(obj1,obj2).start(); new B(obj1,obj2).start(); } } class A extends Thread{ Object obj1 ; Object obj2; public A() { } public A(Object obj1, Object obj2) { super(); this.obj1 = obj1; this.obj2 = obj2; } @Override public void run() { synchronized(obj1){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(obj2){ } } System.out.println("給我煙"); } } class B extends Thread{ Object obj1 ; Object obj2; public B() { } public B(Object obj1, Object obj2) { super(); this.obj1 = obj1; this.obj2 = obj2; } @Override public void run() { synchronized(obj2){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(obj1){ } } System.out.println("給我錢"); } }二、線程通信:生產(chǎn)者消費(fèi)者模式
線程通信的目標(biāo)是使線程間能夠互相發(fā)送信號。另一方面,線程通信使線程能夠等待其
他線程的信號。
Java 有一個內(nèi)建的等待機(jī)制來允許線程在等待信號的時候變?yōu)榉沁\(yùn)行狀態(tài)。
java.lang.Object 類定義了三個方法,wait()、notify()和 notifyAll()來實(shí)現(xiàn)這個等待機(jī)制。一個線程一旦調(diào)用了任意對象的 wait()方法,就會變?yōu)榉沁\(yùn)行狀態(tài),直到另一個線程調(diào)用了同一個對象的 notify()方法。為了調(diào)用 wait()或者 notify(),線程必須先獲得那個對象的鎖。也就是說,線程必須在同步塊里調(diào)用 wait()或者 notify()。
以下為一個使用了 wait()和 notify()實(shí)現(xiàn)的線程間通信的共享對象:
/** * 街道 * @author Administrator * */ public class Street { //紅綠燈 //false 紅燈 -->人等 車走 -->換燈 通知人走 //true 綠燈 -->車等 人走 -->換燈 通知車走 private boolean flag=false; //東西向 -->人道 public synchronized void west(){ if(flag==false){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("東西向-->人走"); //換燈 this.flag =false; this.notify(); //喚醒等待者 } //南北向 車道 public synchronized void north(){ if(flag==true){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("南北向-->車走"); //換燈 this.flag =true; this.notify(); //喚醒等待者 } } class Person extends Thread { private Street s ; public Person(Street s) { this.s = s; } public void run() { for(int i=0;i<10;i++){ s.west(); //東西向 } } } class Car extends Thread { private Street s ; public Car(Street s) { this.s = s; } public void run() { for(int i=0;i<10;i++){ s.north(); } } }
Java多線程的同步和線程通信就介紹到這里,更多技術(shù)干貨請關(guān)注樂字節(jié)。樂字節(jié)原創(chuàng)!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76034.html
摘要:本文對多線程基礎(chǔ)知識進(jìn)行梳理,主要包括多線程的基本使用,對象及變量的并發(fā)訪問,線程間通信,的使用,定時器,單例模式,以及線程狀態(tài)與線程組。源碼采用構(gòu)建,多線程這部分源碼位于模塊中。通知可能等待該對象的對象鎖的其他線程。 本文對多線程基礎(chǔ)知識進(jìn)行梳理,主要包括多線程的基本使用,對象及變量的并發(fā)訪問,線程間通信,lock的使用,定時器,單例模式,以及線程狀態(tài)與線程組。 寫在前面 花了一周時...
摘要:程序執(zhí)行時,至少會有一個線程在運(yùn)行,這個運(yùn)行的線程被稱為主線程。程序的終止是指除守護(hù)線程以外的線程全部終止。多線程程序由多個線程組成的程序稱為多線程程序。線程休眠期間可以被中斷,中斷將會拋出異常。 線程 我們在閱讀程序時,表面看來是在跟蹤程序的處理流程,實(shí)際上跟蹤的是線程的執(zhí)行。 單線程程序 在單線程程序中,在某個時間點(diǎn)執(zhí)行的處理只有一個。 Java 程序執(zhí)行時,至少會有一個線程在運(yùn)行...
摘要:典型地,和被用在等待另一個線程產(chǎn)生的結(jié)果的情形測試發(fā)現(xiàn)結(jié)果還沒有產(chǎn)生后,讓線程阻塞,另一個線程產(chǎn)生了結(jié)果后,調(diào)用使其恢復(fù)。使當(dāng)前線程放棄當(dāng)前已經(jīng)分得的時間,但不使當(dāng)前線程阻塞,即線程仍處于可執(zhí)行狀態(tài),隨時可能再次分得時間。 1、說說進(jìn)程,線程,協(xié)程之間的區(qū)別 簡而言之,進(jìn)程是程序運(yùn)行和資源分配的基本單位,一個程序至少有一個進(jìn)程,一個進(jìn)程至少有一個線程.進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元...
摘要:下面是線程相關(guān)的熱門面試題,你可以用它來好好準(zhǔn)備面試。線程安全問題都是由全局變量及靜態(tài)變量引起的。持有自旋鎖的線程在之前應(yīng)該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網(wǎng)上流傳著,各種面試經(jīng)驗(yàn)及面試題,往往都是一大堆技術(shù)題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關(guān)線程的問題。Java語言一個重要的特點(diǎn)就是內(nèi)置了對并發(fā)的支持,讓Java大受企業(yè)和程序員...
摘要:提供了多線程升級方案將同步替換成了顯示的操作。線程間通信接口可以替代傳統(tǒng)的線程間通信,用替換,用替換,用替換。商品執(zhí)行上述代碼,觀察結(jié)果可以看到,多個線程同時生產(chǎn)消費(fèi),由于指定喚醒互異線程,因此并不會引起錯誤。 JDK 1.5提供了多線程升級方案將同步synchronized替換成了顯示的Lock操作??梢詫?shí)現(xiàn)喚醒、凍結(jié)指定的線程。 Lock接口Lock 實(shí)現(xiàn)提供了比使用 synchr...
閱讀 2999·2021-09-22 15:18
閱讀 3420·2019-08-30 15:54
閱讀 3299·2019-08-30 15:53
閱讀 618·2019-08-30 14:12
閱讀 844·2019-08-29 17:01
閱讀 2228·2019-08-29 14:04
閱讀 1432·2019-08-29 13:09
閱讀 892·2019-08-26 17:40