java文件千鋒多線程_第1頁
java文件千鋒多線程_第2頁
java文件千鋒多線程_第3頁
java文件千鋒多線程_第4頁
java文件千鋒多線程_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、1Thread tsynchronized(obj)obj.wait()obj.notify()線程t得到obj對象的鎖線程t被放置在obj對象的等待池中,并自動釋放obj對象的鎖當某個線程執(zhí)行了obj對象的notify方法后,會喚醒在此對象等待池中的某一個線程obj.notifyAll()當某個線程執(zhí)行了obj對象的notifyAll方法后,會喚醒在此對象等待池中的所有線程線程等待: Object 類中的wait() throws InterruptedException 方法,導(dǎo)致當前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 喚醒方法。線程喚醒

2、:Object 類中的notify()方法,喚醒在此對象監(jiān)視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的。Object類中的notifyAll()方法,喚醒在此對象監(jiān)視器上等待的所有線程。這三個方法只能在被同步化(synchronized)的方法或代碼塊中調(diào)用見生產(chǎn)者消費者示例2生產(chǎn)者(Producer)與消費者(Consumer)的問題生產(chǎn)者將產(chǎn)品交給店員(Clerk),而消費者從店員處取走產(chǎn)品,店員一次只能持有固定數(shù)量的產(chǎn)品,如果生產(chǎn)者生產(chǎn)了過多的產(chǎn)品,店員叫生產(chǎn)者等一下,如果店中有空位放產(chǎn)品了再通知生產(chǎn)者繼續(xù)生產(chǎn);如果店中沒有產(chǎn)品了,店員會告

3、訴消費者等一下,如果店中有產(chǎn)品了再通知消費者來取走產(chǎn)品。TestProduct.java3場景類TestProduct/生產(chǎn)者消費者問題public class TestProduct public static void main(String args) Clerk clerk = new Clerk(0);/生產(chǎn)者線程Thread producerThread = new Thread(new Producer(clerk);/消費者線程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)者處獲取商品(進貨)public synchronized void addProduct()if(duct=20)/貨滿,暫停進貨System.out.println(貨滿,暫停進貨);try wait(); catch (InterruptedException e) e.printStackTrac

5、e();.else/可以進貨duct +;System.out.println(從生產(chǎn)者處獲得了第+duct +個商品);notify();/隨機喚醒一個等待執(zhí)行某個同步方法的對象.店員類Clerk(2)/向消費者兜售商品(賣貨)public synchronized void sellProduct()if(duct=0)System.out.println(售罄,估清,暫停銷售,等待生產(chǎn)者提供商品);try wait(); catch (InterruptedException e) e.printStackTrace();.elseSyst

6、em.out.println(向消費者兜售了第+(duct) +個商品);duct -;notify();消費者類Comsumerpublic class Consumer implements Runnableprivate Clerk clerk;public Consumer(Clerk clerk) super();this.clerk = clerk;public void run() while(true)clerk.sellProduct();/調(diào)用一個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)用一個Clerk類中的同步方法try Thread.sleep(int)(Math.random()*1000); catch

8、 (InterruptedException e) e.printStackTrace();練習(xí)Wife線程類,負責花錢1萬的隨機整數(shù)倍,每次不超過10萬,如果余額不夠但不為0,則有多少就花多少;Husband線程類,負責賺錢,2萬的隨機整數(shù)倍,每次不超過10萬;如果余額超過10萬(含),則wait;如果余額加上新賺的錢超過10萬,則保留(例如余額5萬,新賺6萬,則新余額11萬)Money錢類,下限0元TestMoney場景類,啟動一個Husband線程,啟動兩個Wife線程,模擬賺錢花錢的過程.如果線程的run()方法中執(zhí)行的是一個重復(fù)執(zhí)行的循環(huán),可以提供一個標記來控制循環(huán)是否繼續(xù)執(zhí)行。對于

9、正在執(zhí)行的線程,interrupt()無法打斷該線程的執(zhí)行,但是可以獲得該線程被中斷的標志: Terrupted()得到true,調(diào)用后,中斷標志將被清除(變?yōu)閒alse)如果線程因為執(zhí)行join(),sleep()或是wait()而進入了阻塞狀態(tài),此時要想停止它,可以使用interrupt(),程序會拋出InterruptException異常而被catch()子句捕獲,進行處理。如果程序因為輸入/輸出的等待而阻塞,基本上必須等待輸入/輸出的動作完成才能離開阻塞狀態(tài)。無法用interrupt()方法來使得線程離開run()方法,要想離開,只能通過引發(fā)一個異常。10線程的停止

10、(復(fù)習(xí))interrupt()public void run() System.out.println(1.進入子線程執(zhí)行。);try System.out.println(2.準備睡覺。);Thread.sleep(1000);System.out.println(3.睡到自然醒。); catch (InterruptedException e) System.out.println(誰把我吵醒了? 跟他拼了!);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();/ 打斷一個線程。方法說明start() 新建的線程進入Runnable狀態(tài)run() 線程進入Running 狀態(tài),程序員不要調(diào)用該方法,由系統(tǒng)調(diào)用wait()線程進入等待狀態(tài),等待被notify,這是一個對象方法,而不是線程方法notify()/notifyAll()喚醒其他的線程,這是一個對象方法,而不是線程方法static void yield()暫停當前正在

12、執(zhí)行的線程對象,并執(zhí)行其他線程。 它是一個靜態(tài)方法getPriority()/setPriority()獲得/設(shè)置線程優(yōu)先級1-10 5 5 interrupt()打斷線程執(zhí)行static boolean interrupted()查看線程是否被打斷static void sleep()線程睡眠指定的一段時間join()調(diào)用這個方法的主線程,會等待加入的子線程完成isAlive()判斷一個線程是否還是活動狀態(tài)java.lang.ThreadLocal 線程局部變量用于解決多個線程共享同一個對象時,對象屬性的數(shù)據(jù)安全問題.每一個ThreadLocal對象就像一個整個樓的信箱,每一個線程只能打開其

13、中的一個屬于自己的信箱.這個信箱只能放一個對象.本質(zhì)上ThreadLocal類中有一個Map,用于存儲每一個線程的變量的副本.且無需知道key是什么(其實是當前線程).也不會錯用到其他線程的局部變量.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() /獲取當前線程的名字String currentThreadName = Thread.currentThread().getName();/產(chǎn)生一個隨機數(shù)并打印Random random = new Random();int age = random.nextInt(100);/獲取一個Studen

15、t對象,并將隨機數(shù)年齡插入到對象屬性中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() /獲取本地線程變量并強制轉(zhuǎn)換為Student類型Student student = studentLocal.get();/線程首次執(zhí)行此方法的時候,studentLocal.get()肯定為nullif (student = null) /創(chuàng)建一個Student對象,并保存到本地線程變量studentLocal中student = new Student();studentLocal.set(student);return student;如果兩個或兩個以上的線程都修改一個對象,

17、那么把執(zhí)行修改的方法定義為被同步的,如果對象更新影響到只讀方法,那么只讀方法也要定義成同步的。不要濫用同步。如果在一個對象內(nèi)的不同的方法訪問的不是同一個數(shù)據(jù),就不要將方法設(shè)置為synchronized的。如果一個線程必須等待一個對象狀態(tài)發(fā)生變化,那么他應(yīng)該在對象內(nèi)部等待,而不是在外部。他可以通過調(diào)用一個被同步的方法,并讓這個方法調(diào)用wait()。每當一個方法返回某個對象的鎖時,它應(yīng)當調(diào)用notifyAll()來讓等待隊列中的其他線程有機會執(zhí)行。記住wait()和notify()/notifyAll()是Object類方法,而不是Thread類的方法。仔細查看每次調(diào)用wait()方法,都有相應(yīng)的

18、notify()/notifyAll()方法,且它們均作用于同一個對象。后臺線程(守護線程)Daemon Thread在后臺運行的線程,為其他的線程提供服務(wù)可以用setDaemon(boolean b)來把一個線程設(shè)置成后臺線程經(jīng)常用于任務(wù)結(jié)束時的善后處理典型的后臺線程是定時器Timer線程后臺線程的優(yōu)先級比其他線程的低如果沒有“用戶線程”在運行,JVM將退出,守護線程將被自動終止后臺線程(守護線程)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();典型的后臺線程Timerpublic static void main(String args) Timer timer = new Timer(true);/如果沒有設(shè)置為true,則會一直執(zhí)行timer.schedule(new TimerTask() public void run() /TimerTask實現(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();/主線程終止后,后臺線程會停

21、下來用線程實現(xiàn)接口回調(diào)創(chuàng)建線程時,給線程的構(gòu)造方法傳一個當前類的對象;線程任務(wù)完成時應(yīng)該用該對象調(diào)用某個方法,進行后續(xù)處理;Demo為了更好的擴展性,線程的構(gòu)造方法的形參應(yīng)該聲明成接口類型的,在調(diào)用構(gòu)造方法時傳入實現(xiàn)類的對象,在線程完成工作后用該引用調(diào)用接口中定義的方法(在實現(xiàn)類中做了重寫)Demo通常把一個匿名內(nèi)部類作為實參傳遞給線程類的構(gòu)造方法,在匿名內(nèi)部類中重寫接口中定義的方法. Demo線程 VS 進程創(chuàng)建和啟動線程的方式實現(xiàn)Runnable接口繼承自Thread類線程的狀態(tài)轉(zhuǎn)換線程的調(diào)度和優(yōu)先級sleep,join,yieldsynchronized線程同步死鎖問題線程間的通信wait 、notify / notifyAll生產(chǎn)者、消費者問題

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論