版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1Thread tsynchronized(obj)obj.wait()obj.notify()線程t得到obj對(duì)象的鎖線程t被放置在obj對(duì)象的等待池中,并自動(dòng)釋放obj對(duì)象的鎖當(dāng)某個(gè)線程執(zhí)行了obj對(duì)象的notify方法后,會(huì)喚醒在此對(duì)象等待池中的某一個(gè)線程obj.notifyAll()當(dāng)某個(gè)線程執(zhí)行了obj對(duì)象的notifyAll方法后,會(huì)喚醒在此對(duì)象等待池中的所有線程線程等待: Object 類中的wait() throws InterruptedException 方法,導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 喚醒方法。線程喚醒
2、:Object 類中的notify()方法,喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程。如果所有線程都在此對(duì)象上等待,則會(huì)選擇喚醒其中一個(gè)線程。選擇是任意性的。Object類中的notifyAll()方法,喚醒在此對(duì)象監(jiān)視器上等待的所有線程。這三個(gè)方法只能在被同步化(synchronized)的方法或代碼塊中調(diào)用見生產(chǎn)者消費(fèi)者示例2生產(chǎn)者(Producer)與消費(fèi)者(Consumer)的問(wèn)題生產(chǎn)者將產(chǎn)品交給店員(Clerk),而消費(fèi)者從店員處取走產(chǎn)品,店員一次只能持有固定數(shù)量的產(chǎn)品,如果生產(chǎn)者生產(chǎn)了過(guò)多的產(chǎn)品,店員叫生產(chǎn)者等一下,如果店中有空位放產(chǎn)品了再通知生產(chǎn)者繼續(xù)生產(chǎn);如果店中沒(méi)有產(chǎn)品了,店員會(huì)告
3、訴消費(fèi)者等一下,如果店中有產(chǎn)品了再通知消費(fèi)者來(lái)取走產(chǎn)品。TestProduct.java3場(chǎng)景類TestProduct/生產(chǎn)者消費(fèi)者問(wèn)題public class TestProduct public static void main(String args) Clerk clerk = new Clerk(0);/生產(chǎn)者線程Thread producerThread = new Thread(new Producer(clerk);/消費(fèi)者線程Thread consumerThread = new Thread(new Consumer(clerk);producerThread.start(
4、);consumerThread.start();店員類Clerk(1)public class Clerk public int product;/現(xiàn)存的商品數(shù)量0-20public Clerk(int product) duct = product;/從生產(chǎn)者處獲取商品(進(jìn)貨)public synchronized void addProduct()if(duct=20)/貨滿,暫停進(jìn)貨System.out.println(貨滿,暫停進(jìn)貨);try wait(); catch (InterruptedException e) e.printStackTrac
5、e();.else/可以進(jìn)貨duct +;System.out.println(從生產(chǎn)者處獲得了第+duct +個(gè)商品);notify();/隨機(jī)喚醒一個(gè)等待執(zhí)行某個(gè)同步方法的對(duì)象.店員類Clerk(2)/向消費(fèi)者兜售商品(賣貨)public synchronized void sellProduct()if(duct=0)System.out.println(售罄,估清,暫停銷售,等待生產(chǎn)者提供商品);try wait(); catch (InterruptedException e) e.printStackTrace();.elseSyst
6、em.out.println(向消費(fèi)者兜售了第+(duct) +個(gè)商品);duct -;notify();消費(fèi)者類Comsumerpublic class Consumer implements Runnableprivate Clerk clerk;public Consumer(Clerk clerk) super();this.clerk = clerk;public void run() while(true)clerk.sellProduct();/調(diào)用一個(gè)Clerk類中的同步方法try Thread.sleep(int)(Math.random()*
7、2000); catch (InterruptedException e) e.printStackTrace();生產(chǎn)者類Producerpublic class Producer implements Runnableprivate Clerk clerk;public Producer(Clerk clerk) super();this.clerk = clerk;public void run() while(true)clerk.addProduct();/調(diào)用一個(gè)Clerk類中的同步方法try Thread.sleep(int)(Math.random()*1000); catch
8、 (InterruptedException e) e.printStackTrace();練習(xí)Wife線程類,負(fù)責(zé)花錢1萬(wàn)的隨機(jī)整數(shù)倍,每次不超過(guò)10萬(wàn),如果余額不夠但不為0,則有多少就花多少;Husband線程類,負(fù)責(zé)賺錢,2萬(wàn)的隨機(jī)整數(shù)倍,每次不超過(guò)10萬(wàn);如果余額超過(guò)10萬(wàn)(含),則wait;如果余額加上新賺的錢超過(guò)10萬(wàn),則保留(例如余額5萬(wàn),新賺6萬(wàn),則新余額11萬(wàn))Money錢類,下限0元TestMoney場(chǎng)景類,啟動(dòng)一個(gè)Husband線程,啟動(dòng)兩個(gè)Wife線程,模擬賺錢花錢的過(guò)程.如果線程的run()方法中執(zhí)行的是一個(gè)重復(fù)執(zhí)行的循環(huán),可以提供一個(gè)標(biāo)記來(lái)控制循環(huán)是否繼續(xù)執(zhí)行。對(duì)于
9、正在執(zhí)行的線程,interrupt()無(wú)法打斷該線程的執(zhí)行,但是可以獲得該線程被中斷的標(biāo)志: Terrupted()得到true,調(diào)用后,中斷標(biāo)志將被清除(變?yōu)閒alse)如果線程因?yàn)閳?zhí)行join(),sleep()或是wait()而進(jìn)入了阻塞狀態(tài),此時(shí)要想停止它,可以使用interrupt(),程序會(huì)拋出InterruptException異常而被catch()子句捕獲,進(jìn)行處理。如果程序因?yàn)檩斎?輸出的等待而阻塞,基本上必須等待輸入/輸出的動(dòng)作完成才能離開阻塞狀態(tài)。無(wú)法用interrupt()方法來(lái)使得線程離開run()方法,要想離開,只能通過(guò)引發(fā)一個(gè)異常。10線程的停止
10、(復(fù)習(xí))interrupt()public void run() System.out.println(1.進(jìn)入子線程執(zhí)行。);try System.out.println(2.準(zhǔn)備睡覺。);Thread.sleep(1000);System.out.println(3.睡到自然醒。); catch (InterruptedException e) System.out.println(誰(shuí)把我吵醒了? 跟他拼了!);System.out.println(子線程結(jié)束。);public static void main(String args) Thread t1 = new Thread(new
11、 MyThread08();t1.start();try Thread.sleep(800);/ catch (InterruptedException e) e.printStackTrace();errupt();/ 打斷一個(gè)線程。方法說(shuō)明start() 新建的線程進(jìn)入Runnable狀態(tài)run() 線程進(jìn)入Running 狀態(tài),程序員不要調(diào)用該方法,由系統(tǒng)調(diào)用wait()線程進(jìn)入等待狀態(tài),等待被notify,這是一個(gè)對(duì)象方法,而不是線程方法notify()/notifyAll()喚醒其他的線程,這是一個(gè)對(duì)象方法,而不是線程方法static void yield()暫停當(dāng)前正在
12、執(zhí)行的線程對(duì)象,并執(zhí)行其他線程。 它是一個(gè)靜態(tài)方法getPriority()/setPriority()獲得/設(shè)置線程優(yōu)先級(jí)1-10 5 5 interrupt()打斷線程執(zhí)行static boolean interrupted()查看線程是否被打斷static void sleep()線程睡眠指定的一段時(shí)間join()調(diào)用這個(gè)方法的主線程,會(huì)等待加入的子線程完成isAlive()判斷一個(gè)線程是否還是活動(dòng)狀態(tài)java.lang.ThreadLocal 線程局部變量用于解決多個(gè)線程共享同一個(gè)對(duì)象時(shí),對(duì)象屬性的數(shù)據(jù)安全問(wèn)題.每一個(gè)ThreadLocal對(duì)象就像一個(gè)整個(gè)樓的信箱,每一個(gè)線程只能打開其
13、中的一個(gè)屬于自己的信箱.這個(gè)信箱只能放一個(gè)對(duì)象.本質(zhì)上ThreadLocal類中有一個(gè)Map,用于存儲(chǔ)每一個(gè)線程的變量的副本.且無(wú)需知道key是什么(其實(shí)是當(dāng)前線程).也不會(huì)錯(cuò)用到其他線程的局部變量.public class ThreadLocalDemo implements Runnable private final static ThreadLocal studentLocal = new ThreadLocal();public static void main(String agrs) ThreadLocalDemo td = new ThreadLocalDemo();Threa
14、d t1 = new Thread(td, “a”);/共享數(shù)據(jù)Thread t2 = new Thread(td, b);t1.start();t2.start();public void run() accessStudent();. .public void accessStudent() /獲取當(dāng)前線程的名字String currentThreadName = Thread.currentThread().getName();/產(chǎn)生一個(gè)隨機(jī)數(shù)并打印Random random = new Random();int age = random.nextInt(100);/獲取一個(gè)Studen
15、t對(duì)象,并將隨機(jī)數(shù)年齡插入到對(duì)象屬性中Student student = this.getStudent();student.setAge(age);System.out.println(thread + currentThreadName + first read age is: + student.getAge();try Thread.sleep(500);catch (InterruptedException ex) ex.printStackTrace();System.out.println(thread + currentThreadName + second read age
16、is: + student.getAge();. .protected Student getStudent() /獲取本地線程變量并強(qiáng)制轉(zhuǎn)換為Student類型Student student = studentLocal.get();/線程首次執(zhí)行此方法的時(shí)候,studentLocal.get()肯定為nullif (student = null) /創(chuàng)建一個(gè)Student對(duì)象,并保存到本地線程變量studentLocal中student = new Student();studentLocal.set(student);return student;如果兩個(gè)或兩個(gè)以上的線程都修改一個(gè)對(duì)象,
17、那么把執(zhí)行修改的方法定義為被同步的,如果對(duì)象更新影響到只讀方法,那么只讀方法也要定義成同步的。不要濫用同步。如果在一個(gè)對(duì)象內(nèi)的不同的方法訪問(wèn)的不是同一個(gè)數(shù)據(jù),就不要將方法設(shè)置為synchronized的。如果一個(gè)線程必須等待一個(gè)對(duì)象狀態(tài)發(fā)生變化,那么他應(yīng)該在對(duì)象內(nèi)部等待,而不是在外部。他可以通過(guò)調(diào)用一個(gè)被同步的方法,并讓這個(gè)方法調(diào)用wait()。每當(dāng)一個(gè)方法返回某個(gè)對(duì)象的鎖時(shí),它應(yīng)當(dāng)調(diào)用notifyAll()來(lái)讓等待隊(duì)列中的其他線程有機(jī)會(huì)執(zhí)行。記住wait()和notify()/notifyAll()是Object類方法,而不是Thread類的方法。仔細(xì)查看每次調(diào)用wait()方法,都有相應(yīng)的
18、notify()/notifyAll()方法,且它們均作用于同一個(gè)對(duì)象。后臺(tái)線程(守護(hù)線程)Daemon Thread在后臺(tái)運(yùn)行的線程,為其他的線程提供服務(wù)可以用setDaemon(boolean b)來(lái)把一個(gè)線程設(shè)置成后臺(tái)線程經(jīng)常用于任務(wù)結(jié)束時(shí)的善后處理典型的后臺(tái)線程是定時(shí)器Timer線程后臺(tái)線程的優(yōu)先級(jí)比其他線程的低如果沒(méi)有“用戶線程”在運(yùn)行,JVM將退出,守護(hù)線程將被自動(dòng)終止后臺(tái)線程(守護(hù)線程)Daemon Threadpublic class DaemonThread extends Threadpublic void run()while(true)System.out.printl
19、n(Deamon Thread running.);public static void main(Stringargs)DaemonThread dt = new DaemonThread();dt.setDaemon(true);dt.start();典型的后臺(tái)線程Timerpublic static void main(String args) Timer timer = new Timer(true);/如果沒(méi)有設(shè)置為true,則會(huì)一直執(zhí)行timer.schedule(new TimerTask() public void run() /TimerTask實(shí)現(xiàn)了Runnable接口 C
20、alendar c = Calendar.getInstance(); int hour = c.get(Calendar.HOUR_OF_DAY); int minite = c.get(Calendar.MINUTE); int second = c.get(Calendar.SECOND); System.out.println(hour + : + minite + : + second);, 0,1000);try Thread.sleep(5000); catch (InterruptedException e) e.printStackTrace();/主線程終止后,后臺(tái)線程會(huì)停
21、下來(lái)用線程實(shí)現(xiàn)接口回調(diào)創(chuàng)建線程時(shí),給線程的構(gòu)造方法傳一個(gè)當(dāng)前類的對(duì)象;線程任務(wù)完成時(shí)應(yīng)該用該對(duì)象調(diào)用某個(gè)方法,進(jìn)行后續(xù)處理;Demo為了更好的擴(kuò)展性,線程的構(gòu)造方法的形參應(yīng)該聲明成接口類型的,在調(diào)用構(gòu)造方法時(shí)傳入實(shí)現(xiàn)類的對(duì)象,在線程完成工作后用該引用調(diào)用接口中定義的方法(在實(shí)現(xiàn)類中做了重寫)Demo通常把一個(gè)匿名內(nèi)部類作為實(shí)參傳遞給線程類的構(gòu)造方法,在匿名內(nèi)部類中重寫接口中定義的方法. Demo線程 VS 進(jìn)程創(chuàng)建和啟動(dòng)線程的方式實(shí)現(xiàn)Runnable接口繼承自Thread類線程的狀態(tài)轉(zhuǎn)換線程的調(diào)度和優(yōu)先級(jí)sleep,join,yieldsynchronized線程同步死鎖問(wèn)題線程間的通信wait 、notify / notifyAll生產(chǎn)者、消費(fèi)者問(wèn)題
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(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年外研銜接版九年級(jí)歷史上冊(cè)階段測(cè)試試卷含答案
- 2025年華東師大版選修3物理下冊(cè)階段測(cè)試試卷含答案
- 2025年北師大新版九年級(jí)物理下冊(cè)階段測(cè)試試卷含答案
- 2025年牛津譯林版九年級(jí)歷史下冊(cè)階段測(cè)試試卷含答案
- 2025年北師大版九年級(jí)歷史下冊(cè)階段測(cè)試試卷
- 二零二五版苗木種植基地土壤檢測(cè)與分析合同4篇
- 承包給農(nóng)民工砍筏蘭竹合同(2篇)
- 二零二五年度農(nóng)藥農(nóng)膜環(huán)保處理技術(shù)合同范本4篇
- 二零二五年度泥水工施工技能競(jìng)賽組織與培訓(xùn)合同2篇
- 美容院與醫(yī)療機(jī)構(gòu)合作開展抗衰老服務(wù)合同范本4篇
- 中醫(yī)診療方案腎病科
- 人教版(2025新版)七年級(jí)下冊(cè)數(shù)學(xué)第七章 相交線與平行線 單元測(cè)試卷(含答案)
- 完整2024年開工第一課課件
- 從跨文化交際的角度解析中西方酒文化(合集5篇)xiexiebang.com
- 中藥飲片培訓(xùn)課件
- 醫(yī)院護(hù)理培訓(xùn)課件:《早產(chǎn)兒姿勢(shì)管理與擺位》
- 《論文的寫作技巧》課件
- 空氣自動(dòng)站儀器運(yùn)營(yíng)維護(hù)項(xiàng)目操作說(shuō)明以及簡(jiǎn)單故障處理
- 2022年12月Python-一級(jí)等級(jí)考試真題(附答案-解析)
- T-CHSA 020-2023 上頜骨缺損手術(shù)功能修復(fù)重建的專家共識(shí)
- Hypermesh lsdyna轉(zhuǎn)動(dòng)副連接課件完整版
評(píng)論
0/150
提交評(píng)論