




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Java線程(下) 線程的join()方法 多線程編程 多線程共享數(shù)據(jù) 線程之間的通信線程的join方法 Thread API 包含了等待另一個(gè)線程完成的方法:join() 方法。當(dāng)調(diào)用 Thread.join() 時(shí),調(diào)用線程將阻塞,直到被join方法加入的目標(biāo)線程完成為止。 Thread.join() 通常由使用線程的程序調(diào)用,以將大問題劃分成許多小問題,每個(gè)小問題分配一個(gè)線程。當(dāng)所有的小問題都得到處理后,再調(diào)用主線程來進(jìn)一步操作。join方法例子(示例12-6)JoinThread r = new JoinThread();Thread t = new Thread(r);t.start
2、();try t.join(); catch(InterruptedException e)多線程 多線程編程 多個(gè)線程來自同一個(gè)Runnable實(shí)例 多個(gè)線程使用同樣的數(shù)據(jù)和代碼 例子: Thread t1 = new Thread(object1); Thread t2 = new Thread(object1); 多線程例子(示例12-7) RunningObject ro = new RunningObject();Thread t1 = new Thread(ro,1st);Thread t2 = new Thread(ro,2nd);t1.start();t2.start(); 多
3、線程共享數(shù)據(jù)時(shí)的問題 經(jīng)典的銀行取款問題 有一個(gè)銀行賬戶,還有余額1100元,現(xiàn)在A通過銀行卡從中取1000元,而同時(shí)另外一個(gè)人B通過存折也從這個(gè)賬戶中取1000元。取錢之前,要首先進(jìn)行判斷:如果賬戶中的余額大于要取的金額,則可以執(zhí)行取款操作,否則,將拒絕取款。 我們假定有兩個(gè)線程來分別從銀行卡和存折進(jìn)行取款操作,當(dāng)A線程執(zhí)行完判斷語句后,獲得了當(dāng)前賬戶中的余額數(shù)(1000元),因?yàn)橛囝~大于取款金額,所以準(zhǔn)備執(zhí)行取錢操作(從賬戶中減去1000元),但此時(shí)它被線程B打斷,然后,線程B根據(jù)余額,從中取出1000元,然后,將賬戶里面的余額減去1000元,然后,返回執(zhí)行線程A的動(dòng)作,這個(gè)線程將從上次中
4、斷的地方開始執(zhí)行:也就是說,它將不再判斷賬戶中的余額,而是直接將上次中斷之前獲得的余額減去1000。此時(shí),經(jīng)過兩次的取款操作,賬戶中的余額為100元,從賬面上來看,銀行支出了1000元,但實(shí)際上,銀行支出了2000元。共享數(shù)據(jù)出錯(cuò)例子 堆棧是這樣的數(shù)據(jù)結(jié)構(gòu):它是一個(gè)用于存放數(shù)據(jù)的隊(duì)列,最先進(jìn)入的元素最后一個(gè)被釋放(后進(jìn)先出)。用 push() 方法可以把一個(gè)元素添加到堆棧頂(稱為壓棧),用不指定索引的 pop() 方法可以把一個(gè)元素從堆棧頂釋放出來(稱為出?;驈棗#┏鰲簵9蚕頂?shù)據(jù)出錯(cuò)例子(con.) 以一個(gè)數(shù)組來模擬堆棧(Stack)的操作:一個(gè)方法向堆棧里壓(push in)數(shù)據(jù),一個(gè)方法
5、向外彈出(pop out)數(shù)據(jù),下面是一個(gè)用int類型的數(shù)組來模擬的堆棧:public interface StackInterfacepublic void push(int n);public int pop();共享數(shù)據(jù)出錯(cuò)例子(示例12-8)public class UnsafeStack implements StackInterface private int top = 0; private int values = new int10; public void push(int n) valuestop = n;/1 System.out.println(壓入數(shù)字+n+步驟1完
6、成); top+;/2 System.out.println(壓入數(shù)字完成); public int pop() System.out.print(彈出); top-;/3 int test = valuestop,top;/4 return test; 共享數(shù)據(jù)出錯(cuò)例子(con.)public class TestUnsafeStackpublic static void main(String args)UnsafeStack s = new UnsafeStack();s.push(1);/5s.push(2);/6PushThread r1 = new PushThread(s);Po
7、pThread r2 = new PopThread(s);Thread t1 = new Thread(r1);Thread t2 = new Thread(r2);t1.start(); /7t2.start(); /8共享數(shù)據(jù)出錯(cuò)例子(con.) 語句5:1 /top=1 語句6:12 /top=2 語句7:啟動(dòng)壓棧(push)線程t1 語句8:啟動(dòng)出棧(pop)線程t2 語句1:1215 /top=2 語句2:1215 /top=3 語句3:1215 /top=2 語句4:12 /top=2共享數(shù)據(jù)出錯(cuò)例子(con.) 語句5:1 /top=1 語句6:12 /top=2 語句7:啟動(dòng)
8、壓棧(push)線程t1 語句8:啟動(dòng)出棧(pop)線程t2 語句1:1215 /top=2 語句3:1215 /top=1 語句4:115 /top=1 語句2:115 /top=2互斥鎖 在Java語言中,引入了對(duì)象互斥鎖(mutual exclusive lock,也簡稱為對(duì)象鎖)的概念,來保證共享數(shù)據(jù)操作的完整性: 每個(gè)對(duì)象都對(duì)應(yīng)于一個(gè)可稱為“互斥鎖”的標(biāo)記,這個(gè)標(biāo)記用來保證在任一時(shí)刻,只能有一個(gè)線程訪問該對(duì)象。 關(guān)鍵字synchronized 來與對(duì)象的互斥鎖聯(lián)系。當(dāng)某個(gè)對(duì)象用synchronized修飾時(shí),表明該對(duì)象在任一時(shí)刻只能由一個(gè)線程訪問。關(guān)鍵字synchronized 在J
9、ava中的兩種使用synchronized的方式: 放在方法前面,這樣,調(diào)用該方法的線程均將獲得對(duì)象的鎖。 放在代碼塊前面,它也有兩種形式: synchronized (this) 或synchronized :代碼塊中的代碼將獲得當(dāng)前對(duì)象引用的鎖 synchronized(otherObj) :代碼塊中的代碼將獲得指定對(duì)象引用的鎖釋放鎖 如果一個(gè)線程一直占用一個(gè)對(duì)象的鎖,則其他的線程將永遠(yuǎn)無法訪問該對(duì)象,因此,需要在適當(dāng)?shù)臅r(shí)候,將對(duì)象鎖歸還。 當(dāng)線程執(zhí)行到synchronized()塊結(jié)束時(shí),釋放對(duì)象鎖。 當(dāng)在synchronized()塊中遇到break, return或拋出excepti
10、on,則自動(dòng)釋放對(duì)象鎖。 當(dāng)一個(gè)線程調(diào)用wait()方法時(shí),它放棄擁有的對(duì)象鎖并進(jìn)入等待隊(duì)列。synchronized例子(示例12-8) public void push(int n) synchronized(this) valuestop = n; System.out.println(壓入數(shù)字+n+步驟1完成); top+; System.out.println(壓入數(shù)字完成); public int pop() synchronized(this) System.out.print(彈出); top-; int test = valuestop,top; return test; 死
11、鎖 是指兩個(gè)線程,都相互等待對(duì)方釋放lock 是不可測知或避開的 應(yīng)采取措施避免死鎖的出現(xiàn)對(duì)象的wait()、notify()和notifyAll()方法 Object 類定義了 wait()、notify() 和 notifyAll() 方法??梢宰尵€程相互通知事件的發(fā)生。要執(zhí)行這些方法,必須擁有相關(guān)對(duì)象的鎖。 wait() 會(huì)讓調(diào)用線程休眠,直到用 Terrupt() 中斷它、過了指定的時(shí)間、或者另一個(gè)線程用 notify() 或 notifyAll() 喚醒它。 當(dāng)對(duì)某個(gè)對(duì)象調(diào)用 notify() 時(shí),如果有任何線程正在通過 wait() 等待該對(duì)象,那么就會(huì)喚醒其中一
12、個(gè)線程。當(dāng)對(duì)某個(gè)對(duì)象調(diào)用 notifyAll() 時(shí),會(huì)喚醒所有正在等待該對(duì)象的線程。實(shí)現(xiàn)了線程通信的堆棧類(示例12-9) public void push(int n) synchronized(this) while(dataAvailable) /1 try wait(); catch(InterruptedException e) /忽略 /2 valuestop = n; System.out.println(壓入數(shù)字+n+步驟1完成); top+; dataAvailable = true; notifyAll(); System.out.println(壓入數(shù)字完成); 實(shí)現(xiàn)了
13、線程間通信的堆棧類(con.) public int pop() synchronized(this) while(!dataAvailable) /3 try wait(); catch(InterruptedException e) /忽略 /4 System.out.print(彈出); top-; int test = valuestop,top; dataAvailable = false; notifyAll(); return test; 避免無謂的同步方法 因?yàn)橥綍?huì)降低程序的執(zhí)行效率,所以應(yīng)該避免無謂的同步 通過所謂的Fine-Grained鎖的機(jī)制,可以避免這種情況多線程編
14、程一般規(guī)則 如果兩個(gè)或兩個(gè)以上的線程都修改一個(gè)對(duì)象,那么把執(zhí)行修改的方法定義為被同步的,如果對(duì)象更新影響到只讀方法,那么只讀方法也要定義成同步的。 不要濫用同步。如果在一個(gè)對(duì)象內(nèi)的不同的方法訪問的不是同一個(gè)數(shù)據(jù),就不要將方法設(shè)置為synchronized的。 如果一個(gè)線程必須等待一個(gè)對(duì)象狀態(tài)發(fā)生變化,那么他應(yīng)該在對(duì)象內(nèi)部等待,而不是在外部。他可以通過調(diào)用一個(gè)被同步的方法,并讓這個(gè)方法調(diào)用wait()。 每當(dāng)一個(gè)方法返回某個(gè)對(duì)象的鎖時(shí),它應(yīng)當(dāng)調(diào)用notifyAll()來讓等待隊(duì)列中的其他線程有機(jī)會(huì)執(zhí)行。 記住wait()和notify()/notifyAll()是Object類方法,而不是Thread類的方法。仔細(xì)查看每次調(diào)用wait()方法,都有相應(yīng)的notify()/notifyAll()方法,且它們均作用于同一個(gè)對(duì)象。多線程編程一般規(guī)則
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年合同到期解約申請(qǐng)模板
- 2025年藥店店員合同模板
- 一年級(jí)下冊數(shù)學(xué)教案-兩位數(shù)加減整十?dāng)?shù)、一位數(shù)的口算 (20)-西師大版
- 分?jǐn)?shù)的初步認(rèn)識(shí)(一)練習(xí)十一(教案)2024-2025學(xué)年數(shù)學(xué)三年級(jí)上冊 蘇教版
- 2024年人工種植牙項(xiàng)目投資申請(qǐng)報(bào)告代可行性研究報(bào)告
- 2025年杭州科技職業(yè)技術(shù)學(xué)院單招職業(yè)傾向性測試題庫1套
- 2025屆黑龍江省“六校聯(lián)盟”高三上學(xué)期聯(lián)考化學(xué)試題及答案
- 2025年度教師專業(yè)成長路徑規(guī)劃聘用合同
- 2025年度養(yǎng)老產(chǎn)業(yè)簡易版股份轉(zhuǎn)讓合同模板
- 2025年度文化旅游產(chǎn)業(yè)合作授權(quán)委托書
- 舞臺(tái)設(shè)計(jì)課件
- 高中勞動(dòng)教育課教案8篇
- 急性髓性白血病教學(xué)查房課件
- 高中英語 高中閱讀高頻單詞
- 初一年級(jí)班級(jí)日志記載表(詳)
- 《胃癌課件:病理和分子機(jī)制解析》
- 生產(chǎn)制造企業(yè)流程匯編
- 國際貿(mào)易實(shí)務(wù)課程教案
- 部編版六年級(jí)語文下冊全冊課件PPT
- 人教版三年級(jí)數(shù)學(xué)下冊 (認(rèn)識(shí)東北、西北、東南、西南)位置與方向課件
- 與食品經(jīng)營相適應(yīng)的主要設(shè)備設(shè)施布局、操作流程等文件
評(píng)論
0/150
提交評(píng)論