摘要:上次是說到了多線程的創(chuàng)建和狀態(tài)樂字節(jié),接下來,我們?cè)賮斫又f多線程同步和線程通信生產(chǎn)者消費(fèi)者模式。另一方面,線程通信使線程能夠等待其他線程的信號(hào)。
大家伙周末愉快,小樂又來給大家獻(xiàn)上技術(shù)大餐。上次是說到了Java多線程的創(chuàng)建和狀態(tài)|樂字節(jié),接下來,我們?cè)賮斫又fJava多線程-同步:synchronized 和線程通信:生產(chǎn)者消費(fèi)者模式。
一、同步:synchronized多個(gè)線程同時(shí)訪問一個(gè)對(duì)象,可能造成非線程安全,數(shù)據(jù)可能錯(cuò)誤,所謂同步:就是控制多個(gè)線程同時(shí)訪就是控制多線程操作同一個(gè)對(duì)象時(shí),注意是同一個(gè)對(duì)象,數(shù)據(jù)的準(zhǔn)確性, 確保數(shù)據(jù)安全,但是加入同步后因?yàn)樾枰却?,所以效率相?duì)低下。
如:一個(gè)蘋果,自己一個(gè)人去咬怎么都不會(huì)出問題,但是多個(gè)人同時(shí)去咬,這個(gè)時(shí)候如果控制不好,就可能會(huì)咬到對(duì)方了。 再?gòu)?qiáng)調(diào)一下是一個(gè)蘋果。
12306 中的火車票,為什么搶到票時(shí),需要等待,鎖定席位才付款?這就是確保一張票只能一個(gè)人去購(gòu)買。
1、同步塊synchronized +塊:同步塊
synchronized (引用類型|對(duì)象|類.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ā)送信號(hào)。另一方面,線程通信使線程能夠等待其
他線程的信號(hào)。
Java 有一個(gè)內(nèi)建的等待機(jī)制來允許線程在等待信號(hào)的時(shí)候變?yōu)榉沁\(yùn)行狀態(tài)。
java.lang.Object 類定義了三個(gè)方法,wait()、notify()和 notifyAll()來實(shí)現(xiàn)這個(gè)等待機(jī)制。一個(gè)線程一旦調(diào)用了任意對(duì)象的 wait()方法,就會(huì)變?yōu)榉沁\(yùn)行狀態(tài),直到另一個(gè)線程調(diào)用了同一個(gè)對(duì)象的 notify()方法。為了調(diào)用 wait()或者 notify(),線程必須先獲得那個(gè)對(duì)象的鎖。也就是說,線程必須在同步塊里調(diào)用 wait()或者 notify()。
以下為一個(gè)使用了 wait()和 notify()實(shí)現(xiàn)的線程間通信的共享對(duì)象:
/** * 街道 * @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ù)干貨請(qǐng)關(guān)注樂字節(jié)。樂字節(jié)原創(chuàng)!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/76034.html
摘要:本文對(duì)多線程基礎(chǔ)知識(shí)進(jìn)行梳理,主要包括多線程的基本使用,對(duì)象及變量的并發(fā)訪問,線程間通信,的使用,定時(shí)器,單例模式,以及線程狀態(tài)與線程組。源碼采用構(gòu)建,多線程這部分源碼位于模塊中。通知可能等待該對(duì)象的對(duì)象鎖的其他線程。 本文對(duì)多線程基礎(chǔ)知識(shí)進(jìn)行梳理,主要包括多線程的基本使用,對(duì)象及變量的并發(fā)訪問,線程間通信,lock的使用,定時(shí)器,單例模式,以及線程狀態(tài)與線程組。 寫在前面 花了一周時(shí)...
摘要:程序執(zhí)行時(shí),至少會(huì)有一個(gè)線程在運(yùn)行,這個(gè)運(yùn)行的線程被稱為主線程。程序的終止是指除守護(hù)線程以外的線程全部終止。多線程程序由多個(gè)線程組成的程序稱為多線程程序。線程休眠期間可以被中斷,中斷將會(huì)拋出異常。 線程 我們?cè)陂喿x程序時(shí),表面看來是在跟蹤程序的處理流程,實(shí)際上跟蹤的是線程的執(zhí)行。 單線程程序 在單線程程序中,在某個(gè)時(shí)間點(diǎn)執(zhí)行的處理只有一個(gè)。 Java 程序執(zhí)行時(shí),至少會(huì)有一個(gè)線程在運(yùn)行...
摘要:典型地,和被用在等待另一個(gè)線程產(chǎn)生的結(jié)果的情形測(cè)試發(fā)現(xiàn)結(jié)果還沒有產(chǎn)生后,讓線程阻塞,另一個(gè)線程產(chǎn)生了結(jié)果后,調(diào)用使其恢復(fù)。使當(dāng)前線程放棄當(dāng)前已經(jīng)分得的時(shí)間,但不使當(dāng)前線程阻塞,即線程仍處于可執(zhí)行狀態(tài),隨時(shí)可能再次分得時(shí)間。 1、說說進(jìn)程,線程,協(xié)程之間的區(qū)別 簡(jiǎn)而言之,進(jìn)程是程序運(yùn)行和資源分配的基本單位,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元...
摘要:下面是線程相關(guān)的熱門面試題,你可以用它來好好準(zhǔn)備面試。線程安全問題都是由全局變量及靜態(tài)變量引起的。持有自旋鎖的線程在之前應(yīng)該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網(wǎng)上流傳著,各種面試經(jīng)驗(yàn)及面試題,往往都是一大堆技術(shù)題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關(guān)線程的問題。Java語言一個(gè)重要的特點(diǎn)就是內(nèi)置了對(duì)并發(fā)的支持,讓Java大受企業(yè)和程序員...
摘要:提供了多線程升級(jí)方案將同步替換成了顯示的操作。線程間通信接口可以替代傳統(tǒng)的線程間通信,用替換,用替換,用替換。商品執(zhí)行上述代碼,觀察結(jié)果可以看到,多個(gè)線程同時(shí)生產(chǎn)消費(fèi),由于指定喚醒互異線程,因此并不會(huì)引起錯(cuò)誤。 JDK 1.5提供了多線程升級(jí)方案將同步synchronized替換成了顯示的Lock操作。可以實(shí)現(xiàn)喚醒、凍結(jié)指定的線程。 Lock接口Lock 實(shí)現(xiàn)提供了比使用 synchr...
閱讀 3122·2021-09-22 15:18
閱讀 3546·2019-08-30 15:54
閱讀 3399·2019-08-30 15:53
閱讀 733·2019-08-30 14:12
閱讀 976·2019-08-29 17:01
閱讀 2342·2019-08-29 14:04
閱讀 1564·2019-08-29 13:09
閱讀 990·2019-08-26 17:40