




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、java 并發(fā)的處理方式1 什么是并發(fā)問(wèn)題。 多個(gè)進(jìn)程或線程同時(shí)(或著說(shuō)在同一段時(shí)間內(nèi) )訪問(wèn)同一資源會(huì)產(chǎn)生并發(fā)問(wèn)題。銀行兩操作員同時(shí)操作同一賬戶(hù)就是典型的例子。比如 A、 B 操作員同時(shí)讀取一余額為 1000 元的賬戶(hù), A 操作員為該賬戶(hù)增加 100 元,B 操作員同時(shí)為該賬戶(hù)減去50 元,A先提交,B后提交。 最后實(shí)際賬戶(hù)余額為1000-50=950元,但本該為1000+100-50=1050。這就是典型的并發(fā)問(wèn)題。如何解決?可以用鎖。用法1public class Testpublic synchronized void print().;某線程執(zhí)行print() 方法,則該對(duì)象將加鎖
2、。其它線程將無(wú)法執(zhí)行該對(duì)象的所有synchronized塊。用法2public classTestpublic void print()synchronized(this)/鎖住本對(duì)象.;同用法 1, 但更能體現(xiàn)synchronized用法的本質(zhì)。用法3public class Testprivate String a = test;public void print()synchronized(a)/鎖住 a 對(duì)象.;public synchronized void t().; / 這個(gè)同步代碼塊不會(huì)因?yàn)閜rint()而鎖定.執(zhí)行 print() ,會(huì)給對(duì)象 a 加鎖,注意不是給Test 的
3、對(duì)象加鎖,也就是說(shuō)Test 對(duì)象的其它synchronized方法不會(huì)因?yàn)閜rint() 而被鎖。同步代碼塊執(zhí)行完,則釋放對(duì)a 的鎖。為了鎖住一個(gè)對(duì)象的代碼塊而不影響該對(duì)象其它synchronized塊的高性能寫(xiě)法:public class Testprivate byte lock = new byte0;public void print()synchronized(lock).;public synchronized void t().;靜態(tài)方法的鎖public class Testpublic synchronized static void execute().;效果同 public
4、 class Testpublic static void execute()synchronized(TestThread.class).;3 Java 中的鎖與排隊(duì)上廁所。鎖就是阻止其它進(jìn)程或線程進(jìn)行資源訪問(wèn)的一種方式,即鎖住的資源不能被其它請(qǐng)求訪問(wèn)。在 JAVA 中,sychronized關(guān)鍵字用來(lái)對(duì)一個(gè)對(duì)象加鎖。比如 :public class MyStack int idx = 0;char data = new char6;public synchronizedvoid push(char c) dataidx = c;idx+;public synchronized char p
5、op() idx-;return dataidx;public static void main(String args) MyStack m = new MyStack();/*下面對(duì)象 m 被加鎖。 嚴(yán)格的說(shuō)是對(duì)象m 的所有synchronized無(wú)法執(zhí)行 m塊被加鎖。如果存在另一個(gè)試圖訪問(wèn)對(duì)象的 push 和pop 方法。m 的線程T,那么T*/m.pop();/ 對(duì)象 m 被加鎖。Java 的加鎖解鎖跟多個(gè)人排隊(duì)等一個(gè)公共廁位完全一樣。第一個(gè)人進(jìn)去后順手把門(mén)從里面鎖住,其它人只好排隊(duì)等。第一個(gè)人結(jié)束后出來(lái)時(shí),門(mén)才會(huì)打開(kāi)(解鎖)。輪到第二個(gè)人進(jìn)去,同樣他又會(huì)把門(mén)從里面鎖住,其它人繼續(xù)排隊(duì)
6、等待。用廁所理論可以很容易明白: 一個(gè)人進(jìn)了一個(gè)廁位,這個(gè)廁位就會(huì)鎖住,但不會(huì)導(dǎo)致另一個(gè)廁位也被鎖住,因?yàn)橐粋€(gè)人不能同時(shí)蹲在兩個(gè)廁位里。對(duì)于 Java就是說(shuō): Java 中的鎖是針對(duì)同一個(gè)對(duì)象的,不是針對(duì)class 的??聪吕?MyStatckm1 = new MyStack();MyStatck m2 = new Mystatck();m1.pop();m2.pop();m1 對(duì)象的鎖是不會(huì)影響 m2 的鎖的,因?yàn)樗鼈儾皇峭粋€(gè)廁位。就是說(shuō),假設(shè)有 3 線程 t1,t2,t3 操作 m1 ,那么這 3 個(gè)線程只可能在 m1 上排隊(duì)等,假設(shè)另 2 個(gè)線程 t8,t9 在操作 m2 ,那么 t
7、8,t9 只會(huì)在 m2 上等待。而 t2 和 t8 則沒(méi)有關(guān)系,即使 m2 上的鎖釋放了, t1,t2,t3 可能仍要在 m1 上排隊(duì)。原因無(wú)它, 不是同一個(gè)廁位耳。 Java 不能同時(shí)對(duì)一個(gè)代碼塊加兩個(gè)鎖,這和數(shù)據(jù)庫(kù)鎖機(jī)制不同,數(shù)據(jù)庫(kù)可以對(duì)一條記錄同時(shí)加好幾種不同的鎖,請(qǐng)參見(jiàn):6b151b9a3.html4 何時(shí)釋放鎖?一般是執(zhí)行完畢同步代碼塊(鎖住的代碼塊)后就釋放鎖,也可以用wait() 方式半路上釋放鎖。wait() 方式就好比蹲廁所到一半,突然發(fā)現(xiàn)下水道堵住了,不得已必須出來(lái)站在一邊, 好讓修下水道師傅(準(zhǔn)備執(zhí)行 notify 的一個(gè)線程)進(jìn)去疏通馬桶,疏通完畢,師傅大喊一聲: 已經(jīng)
8、修好了(notify) ,剛才出來(lái)的同志聽(tīng)到后就重新排隊(duì)。注意啊, 必須等師傅出來(lái)啊,師傅不出來(lái),誰(shuí)也進(jìn)不去。也就是說(shuō)notify后,不是其它線程馬上可以進(jìn)入封鎖區(qū)域活動(dòng)了,而是必須還要等 notify 代碼所在的封鎖區(qū)域執(zhí)行完畢從而釋放鎖以后,其它線程才可進(jìn)入。這里是wait 與 notify 代碼示例: publicsynchronized char pop() char c;while (buffer.size() = 0) try this.wait(); / 從廁位里出來(lái) catch (InterruptedException e) / ignore it.c = (Characte
9、r)buffer.remove(buffer.size()-1).charValue();return c;public synchronized void push(char c) this.notify(); / 通知那些wait() 的線程重新排隊(duì)。注意:僅僅是通知它們重新排隊(duì)。Character charObj = new Character(c);buffer.addElement(charObj);/ 執(zhí)行完畢,釋放鎖。那些排隊(duì)的線程就可以進(jìn)來(lái)了。再深入一些。 由于 wait() 操作而半路出來(lái)的同志沒(méi)收到notify信號(hào)前是不會(huì)再排隊(duì)的, 他會(huì)在旁邊看著這些排隊(duì)的人(其中修水管師
10、傅也在其中) 。注意,修水管的師傅不能插隊(duì),也得跟那些上廁所的人一樣排隊(duì),不是說(shuō)一個(gè)人蹲了一半出來(lái)后,修水管師傅就可以突然冒出來(lái)然后立刻進(jìn)去搶修了,他要和原來(lái)排隊(duì)的那幫人公平競(jìng)爭(zhēng),因?yàn)樗彩莻€(gè)普通線程。如果修水管師傅排在后面,則前面的人進(jìn)去后,發(fā)現(xiàn)堵了,就 wait ,然后出來(lái)站到一邊,再進(jìn)去一個(gè),再 wait ,出來(lái),站到一邊, 只到師傅進(jìn)去執(zhí)行 notify. 這樣,一會(huì)兒功夫, 排隊(duì)的旁邊就站了一堆人,等著 notify. 終于,師傅進(jìn)去,然后 notify 了,接下來(lái)呢? 1. 有一個(gè) wait 的人(線程)被通知到。2. 為什么被通知到的是他而不是另外一個(gè)wait 的人?取決于 JV
11、M. 我們無(wú)法預(yù)先判斷出哪一個(gè)會(huì)被通知到。也就是說(shuō),優(yōu)先級(jí)高的不一定被優(yōu)先喚醒,等待時(shí)間長(zhǎng)的也不一定被優(yōu)先喚醒,一切不可預(yù)知!(當(dāng)然,如果你了解該JVM 的實(shí)現(xiàn),則可以預(yù)知) 。3. 他(被通知到的線程)要重新排隊(duì)。4. 他會(huì)排在隊(duì)伍的第一個(gè)位置嗎?回答是: 不一定。他會(huì)排最后嗎?也不一定。但如果該線程優(yōu)先級(jí)設(shè)的比較高,那么他排在前面的概率就比較大。5. 輪到他重新進(jìn)入廁位時(shí),他會(huì)從上次wait() 的地方接著執(zhí)行,不會(huì)重新執(zhí)行。惡心點(diǎn)說(shuō)就是,他會(huì)接著拉巴巴,不會(huì)重新拉。6. 如果師傅 notifyAll(). 則那一堆半途而廢出來(lái)的人全部重新排隊(duì)。順序不可知。Java DOC上說(shuō), The
12、awakened threads will not be able toproceed until the current thread relinquishes the lock onthis object( 當(dāng)前線程釋放鎖前,喚醒的線程不能去執(zhí)行) 。這用廁位理論解釋就是顯而易見(jiàn)的事。5 Lock的使用用synchronized關(guān)鍵字可以對(duì)資源加鎖。用Lock關(guān)鍵字也可以。它是 JDK1.5 中新增內(nèi)容。用法如下:classBoundedBuffer final Lock lock = new ReentrantLock();final Condition notFull= lock.ne
13、wCondition();final Condition notEmpty = lock.newCondition();final Object items = new Object100;int putptr, takeptr, count;public void put(Object x)throws InterruptedException lock.lock();try while (count = items.length)notFull.await();itemsputptr = x;if (+putptr = items.length) putptr = 0;+count;not
14、Empty.signal(); finally lock.unlock();public Object take() throws InterruptedExceptionlock.lock();try while (count = 0)notEmpty.await();Object x = itemstakeptr;if (+takeptr = items.length) takeptr = 0;-count;notFull.signal();return x; finally lock.unlock();(注:這是 JavaDoc里的例子,是一個(gè)阻塞隊(duì)列的實(shí)現(xiàn)例子。所謂阻塞隊(duì)列,就是一個(gè)隊(duì)
15、列如果滿(mǎn)了或者空了,都會(huì)導(dǎo)致線程阻塞等待。 Java 里的ArrayBlockingQueue提供了現(xiàn)成的阻塞隊(duì)列,不需要自己專(zhuān)門(mén)再寫(xiě)一個(gè)了。)一個(gè)對(duì)象的lock.lock() 和 lock.unlock() 之間的代碼將會(huì)被鎖住。 這種方式比起 synchronize 好在什么地方?簡(jiǎn)而言之, 就是對(duì) wait 的線程進(jìn)行了分類(lèi)。用廁位理論來(lái)描述,則是那些蹲了一半而從廁位里出來(lái)等待的人原因可能不一樣,有的是因?yàn)轳R桶堵了,有的是因?yàn)轳R桶沒(méi)水了。通知 (notify) 的時(shí)候,就可以喊:因?yàn)轳R桶堵了而等待的過(guò)來(lái)重新排隊(duì)(比如馬桶堵塞問(wèn)題被解決了),或者喊,因?yàn)轳R桶沒(méi)水而等待的過(guò)來(lái)重新排隊(duì) (比如馬桶沒(méi)水問(wèn)題被解決了)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 專(zhuān)利法期末試題及答案
- 科學(xué)復(fù)習(xí)方法促進(jìn)知識(shí)掌握試題及答案
- 母豬護(hù)理的法律法規(guī)問(wèn)題試題及答案
- 測(cè)量員初級(jí) 試題及答案
- 網(wǎng)絡(luò)規(guī)劃設(shè)計(jì)師考試內(nèi)容及形式的細(xì)節(jié)分析試題及答案
- 5g應(yīng)用試題及答案
- 簡(jiǎn)單面試題及答案
- 熱點(diǎn)稅務(wù)問(wèn)題的趨勢(shì)分析試題及答案
- 學(xué)習(xí)反饋2025年計(jì)算機(jī)二級(jí)考試試題及答案
- 系統(tǒng)架構(gòu)設(shè)計(jì)的文化背景考題試題及答案
- 2024年高等教育文學(xué)類(lèi)自考-06050人際關(guān)系心理學(xué)考試近5年真題附答案
- 福建省公路水運(yùn)工程試驗(yàn)檢測(cè)費(fèi)用參考指標(biāo)
- 信創(chuàng)虛擬化及云平臺(tái)解決方案
- ICD-10疾病編碼完整版
- 人教小學(xué)二年級(jí)數(shù)學(xué)下冊(cè)有余數(shù)的除法第3課時(shí)《除法豎式》示范教學(xué)課件
- 2024年下半年教師資格考試高中思想政治學(xué)科知識(shí)與教學(xué)能力測(cè)試試卷及答案解析
- 2024年全國(guó)軟件水平考試之中級(jí)數(shù)據(jù)庫(kù)系統(tǒng)工程師考試經(jīng)典測(cè)試題(詳細(xì)參考解析)
- 集團(tuán)企業(yè)運(yùn)行與國(guó)資監(jiān)管數(shù)據(jù)平臺(tái)解決方案
- 中考字音字形練習(xí)題(含答案)-字音字形專(zhuān)項(xiàng)訓(xùn)練
- JTT 1501-2024 潛水作業(yè)現(xiàn)場(chǎng)安全監(jiān)管要求(正式版)
- 盜竊刑事案件案例分析報(bào)告
評(píng)論
0/150
提交評(píng)論