第六章多線程第06章_第1頁
第六章多線程第06章_第2頁
第六章多線程第06章_第3頁
第六章多線程第06章_第4頁
第六章多線程第06章_第5頁
已閱讀5頁,還剩60頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第6章多線程2不憤不啟,不悱不發(fā)。不憤不啟,不悱不發(fā)。舉一隅而不以三隅反,則不復也。舉一隅而不以三隅反,則不復也。3討論正方:選擇越多越幸福反方:選擇越多越痛苦4回顧與作業(yè)點評請描述什么是請描述什么是JavaJava反射機制反射機制?請介紹獲取請介紹獲取ClassClass類有哪幾種方法類有哪幾種方法?在前一章中我們重點介紹了哪幾個類?在前一章中我們重點介紹了哪幾個類?5預習檢查 檢查是否畫出本章思維導圖。 什么是進程?什么是線程? 線程有幾種狀態(tài)?內(nèi)容進度多線程創(chuàng)建和使用線程線程控制共享數(shù)據(jù)線程死鎖和協(xié)作6什么是線程 線程可以稱為輕量級進程,它和進程一樣擁有獨立的執(zhí)行路徑。線程和進程的區(qū)別在

2、于,線程存在于進程中,擁有獨立的執(zhí)行堆棧和程序計數(shù)器,沒有獨立的存儲空間,而是和所屬進程中的其它線程共享存儲空間。 程序和進程的關系,可以理解為:程序是一段靜態(tài)的代碼,是應用程序執(zhí)行的藍本,而進程是指一種正在運行的程序,在內(nèi)存中運行,有獨立的地址空間。7線程的特點8多線程 傳統(tǒng)的程序,一個進程里只有一個線程,所以也稱為單線程程序,而多線程程序是一個進程里擁有多個線程910進程和線程的關系每個家庭成員每個家庭成員-線程線程家庭成員共同擁有-資源 家庭家庭 - -進程進程進程與線程 進程的缺點:CPU每調(diào)度一個進程,都要將其上次被執(zhí)行的情況恢復到CPU和寄存器中去,由于每個進程都有自己的數(shù)據(jù)段、棧

3、段和代碼段,這樣的恢復現(xiàn)場工作需要占用大量系統(tǒng)資源。在多任務操作系統(tǒng),會周期性地將CPU時間劃分給每個進程,使操作系統(tǒng)得以同時執(zhí)行一個以上的進程(或說程序),并讓每個進程都像獨立運行一樣。 線程的優(yōu)點:線程是一種輕量級的進程,他是一個程序中實現(xiàn)單一功能的一個指令序列,他是一個進程的一部分,不能單獨運行,它必須在一個進程之內(nèi)運行或者說是在一個程序的環(huán)境中運行。1112線程的基本狀態(tài)及轉(zhuǎn)換圖時間片用光131、下列說法中錯誤的一項是( ) A.線程就是程序 B.線程是一個程序的單個執(zhí)行流 C.多線程是指一個程序的多個執(zhí)行流 D.線程用于實現(xiàn)并發(fā)2、下列說法中錯誤的一項是( ) A.Java中的第一個

4、線程都屬于某個線程組 B.線程只能在其創(chuàng)建時設置所屬的線程組 C.線程創(chuàng)建之后,可以從一個線程組轉(zhuǎn)移到另一個線程組 D.新建的線程默認情況下屬于其父線程所屬的線程組3、下列說法中錯誤的一項是( ) A、線程是進程的執(zhí)行單元 B、一個進程允許有多個線程,而一個線程至少有一個父進程 C、一個線程可以和刪除另外一個線程 D、同一個進程中的不同線程之間不能并發(fā)執(zhí)行課堂小結(jié)ACD現(xiàn)場提問:內(nèi)容進度多線程創(chuàng)建和使用線程線程控制共享數(shù)據(jù)線程死鎖和協(xié)作14創(chuàng)建和啟動線程 創(chuàng)建線程有兩種方式:擴展java.lang.Thread實現(xiàn)java.lang.Runnable接口方式方式1 1:擴展:擴展java.la

5、ng.Threadjava.lang.Threadclass class 類名類名 extends Thread extends Thread/屬性/其他方法public void run()/線程需要執(zhí)行的核心代碼方式方式2 2:實現(xiàn):實現(xiàn)java.lang.Runnablejava.lang.Runnable接口接口class class 類名類名 implements Runnable implements Runnable/屬性/其他方法public void run()/線程需要執(zhí)行的核心代碼 15多線程的使用16 使用線程的步驟:定義一個線程創(chuàng)建線程的實例啟動線程終止線程多線程的使

6、用public class TestThread public static void main(String args) throws InterruptedException Thread t1 = new MyThread1();MyThread2 mt2 = new MyThread2();Thread t2 = new Thread(mt2);t1.start();t2.start();/繼承自Thread類創(chuàng)建線程類class MyThread1 extends Thread private int i = 0; /無參構(gòu)造方法,調(diào)用父類構(gòu)造方法設置線程名稱 public MyTh

7、read1() super(我的線程1); /通過循環(huán)判斷,輸出10次,每次間隔0.5秒 public void run() try while(i 10) System.out.println(this.getName() + 運行第 + (i+1) + 次); i+; /在指定的毫秒數(shù)內(nèi)讓當前正在執(zhí)行的線程休眠(暫停執(zhí)行) sleep(500); catch(Exception e) e.printStackTrace(); /實現(xiàn)Runnable接口創(chuàng)建線程類class MyThread2 implements RunnableString name = 我的線程2;public voi

8、d run() System.out.println();線程睡眠,讓出CPU執(zhí)行時間實現(xiàn)Runnable接口中的方法17課堂練習00:30318案例描述案例描述: : 通過Thread實現(xiàn)線程;效果圖效果圖: :K練習內(nèi)容練習時間:15分鐘K=案例案例一一19案例描述案例描述: :通過Runnable實現(xiàn)線程;效果圖效果圖: :K練習內(nèi)容練習時間:15分鐘K=案例案例二二20共性問題解決21 常見調(diào)試問題及解決辦法 代碼規(guī)范問題共性問題221、下列說法中錯誤的一項是( )A.一個線程是一個Thread類的實例B.線程從傳遞給純種的Runnable實例run()方法開始執(zhí)行C

9、.線程操作的數(shù)據(jù)來自Runnable實例D.新建的線程調(diào)用start()方法就能立即進入運行狀態(tài) 2、下列關于Thread類提供的線程控制方法的說法中,錯誤的一項是( )A.在線程A中執(zhí)行線程B的join()方法,則線程A等待直到B執(zhí)行完成B.線程A通過調(diào)用interrupt()方法來中斷其阻塞狀態(tài)C.若線程A調(diào)用方法isAlive()返回值為true,則說明A正在執(zhí)行中D.currentThread()方法返回當前線程的引用課堂小結(jié)DD現(xiàn)場提問:內(nèi)容進度多線程創(chuàng)建和使用線程線程控制共享數(shù)據(jù)線程死鎖和協(xié)作23線程的控制 線程控制的方法: void start():使該線程開始啟動,Java 虛

10、擬機負責調(diào)用該線程的 run() 方法。 void sleep(long millis):靜態(tài)方法,線程進入阻塞狀態(tài),在指定時間(單位為毫秒)到達之后進入就緒狀態(tài)。 void yield():靜態(tài)方法,當前線程放棄占用CPU資源,回到就緒狀態(tài),使其他優(yōu)先級不低于此線程的線程有機會被執(zhí)行。 void join() :當前線程等待加入(join)的線程完成,才能繼續(xù)往下執(zhí)行。 void interrupt():中斷線程的阻塞狀態(tài)(而非中斷線程)。 void isAlive():判定該線程是否處于活動狀態(tài),處于就緒、運行和阻塞狀態(tài)的都屬于活動狀態(tài)。 void setPriority(int newP

11、riority):設置當前線程的優(yōu)先級。 int getPriority():獲得當前線程的優(yōu)先級。24終止線程3-1 需求:計數(shù)功能,每間隔2秒輸出1、2、3一直到100結(jié)束。當用戶想中止這個計數(shù)功能時,只要在控制臺輸入s即可。25終止線程3-2import java.util.Scanner;public class EndingThreadpublic static void main(String args) CountThread t = new CountThread();t.start();Scanner scanner = new Scanner(System.in);Syst

12、em.out.println(如果想終止輸出計數(shù)線程,請輸入s);while(true)String s = scanner.nextLine();if(s.equals(s)t.stopIt();break;26終止線程3-3/計數(shù)功能線程class CountThread extends Thread private int i = 0; public CountThread() super(計數(shù)線程); /通過設置i=100,讓線程終止 public void stopIt() i = 100; public void run() try while(i 100) System.out.

13、println(this.getName() + 計數(shù): + (i+1);i+;sleep(2000); catch(Exception e) e.printStackTrace(); 實現(xiàn)循環(huán)計數(shù)27線程等待和中斷等待public class InterruptThreadpublic static void main(String args) CountThread t = new CountThread();t.start();tryThread.sleep(6000);catch(InterruptedException e)e.printStackTrace();/中斷線程的阻塞狀態(tài)

14、(而非中斷線程)errupt();28線程等待和中斷等待class CountThread extends Thread private int i = 0; public CountThread()super(計數(shù)線程); public void run()while(i 100) trySystem.out.println(this.getName() + 計數(shù): + (i+1);i+;Thread.sleep(5000); catch(InterruptedException e)System.out.println(程序捕獲了InterruptedException異常!);

15、 System.out.println(計數(shù)線程運行1次!); 29守護線程public class DaemonThreadpublic static void main(String args) DThread t = new DThread();t.start();System.out.println(讓一切都結(jié)束吧);private static class DThread extends Thread/在無參構(gòu)造方法中設置本線程為守護線程public DThread() setDaemon(true);public void run() while(true)System.out.p

16、rintln(我是后臺線程);該線程屬于創(chuàng)建它的線程,當主線程結(jié)束時該線程也跟著結(jié)束。30課堂練習00:30331案例描述案例描述: : 編寫JAVA程序,實現(xiàn)守護線程,一個守護線程要隨著主線程的終止 而終止; 效果圖效果圖: :K練習內(nèi)容練習時間:15分鐘K=案例案例一一32案例描述案例描述: :線程方法join使用; 效果圖效果圖: :K練習內(nèi)容練習時間:15分鐘K=案例案例二二33共性問題解決34 常見調(diào)試問題及解決辦法 代碼規(guī)范問題共性問題內(nèi)容進度多線程創(chuàng)建和使用線程線程控制共享數(shù)據(jù)線程死鎖和協(xié)作35線程間共享數(shù)據(jù)2-1public class ShareData static int

17、 data = 0; /定義了一個充當鎖的對象:lock,注意lock被定義為static static final Object lock = new Object(); public static void main(String args)ShareThread1 st1 = new ShareThread1();ShareThread2 st2 = new ShareThread2();new Thread(st1).start();new Thread(st2).start(); private static class ShareThread1 implements Runnabl

18、e public void run() /對lock對象上鎖synchronized(lock) while(data 10) try Thread.sleep(1000); System.out.println(這個小于10的數(shù)據(jù)是: + data+); catch (InterruptedException e) e.printStackTrace(); 靜態(tài)內(nèi)部類線程創(chuàng)建測試線程36線程間共享數(shù)據(jù)2-2private static class ShareThread2 implements Runnablepublic void run() /對lock對象上鎖 synchronized

19、(lock)while(data 100) data+;System.out.println(ShareThread2執(zhí)行完后data的值為: + data); 靜態(tài)內(nèi)部類線程37多線程同步 多線程同步依靠的是對象鎖機制,synchronized關鍵字就是利用鎖來實現(xiàn)對共享資源的互斥訪問。 理解同步和鎖:Java用監(jiān)視器的手段來完成線程的同步。監(jiān)視器給受保護的資源外面加了一把鎖,而這把鎖只有一把鑰匙,每一個線程只有在得到這把鑰匙之后才可以對被保護的資源執(zhí)行操作,這線程執(zhí)行操作完成之后,再將這把鑰匙交給下一個即將對所要保護資源進行操作的線程,而其他的線程只能等待,直到拿到這把鑰匙。38使用同步

20、Java中用關鍵字synchronized來完成監(jiān)視器這一角色。 synchronized同步關鍵字的兩種使用方式:任何時刻那些被多個線程共享的資源的操作應放在同步方法或同步塊中完成。 聲明同步方法:public synchronized void synchronizedMethod( )/同步操作方法體 同步代碼塊:synchronized (需要同步操作的對象) /同步對象操作的語句39多線程同步publicclassTestSyncThread2publicstaticvoidmain(Stringargs)/創(chuàng)建一個線程之間競爭使用的對象Objectobj=newObject();f

21、or(inti=0;i5;i+)newThread(newSyncThread(i,obj).start();class SyncThread implements java.lang.Runnable private int tid; private Object lock; /同步鎖 /構(gòu)造方法引入競爭對象 public SyncThread(int id, Object obj) this.tid = id; this.lock = obj; public void run() synchronized(lock) for (int i = 0; i 10; i+) System.out

22、.println(線程ID名為: + this.tid + 正在輸出: + i); 同步代碼塊40課堂練習00:30341案例描述案例描述: :線程互斥訪問(一個資源被一個線程使用結(jié)束,該資源才能被其他線程調(diào)用); 效果圖效果圖: :K練習內(nèi)容練習時間:30分鐘K=案例案例一一42共性問題解決43 常見調(diào)試問題及解決辦法 代碼規(guī)范問題共性問題441、下列說法中錯誤的一項是( ) A、共享數(shù)據(jù)的所有訪問都必須使用synchronized加鎖 B、共享數(shù)據(jù)的訪問不一定全部使用synchronized加鎖 C、所有的對共享數(shù)據(jù)的訪問都是臨界區(qū) D、臨界區(qū)必須使用syschronized標識 2、下列

23、有關線程的敘述中正確的一項是( ) A、一旦一個線程被創(chuàng)建,它就立即開始運行 B、使用start()方法可以使一個線程成為可運行的,但是它不一定立即開始運行 C、當一個線程因為搶占機制而停止運行時,它被放在可運行隊列的前面 D、一個線程可能因為不同的原因而終止并進入終止狀態(tài)課堂小結(jié)BB現(xiàn)場提問:內(nèi)容進度多線程創(chuàng)建和使用線程線程控制共享數(shù)據(jù)線程死鎖和協(xié)作45什么是死鎖46同步中的死鎖問題 如果有兩個或兩個以上的線程都訪問了多個資源,而這些線程占用了一些資源的同時又在等待其它線程占用的資源,也就是說多個線程之間都持有了對方所需的資源,而又相互等待對方釋放的資源。在這種情況下就會出現(xiàn)死鎖。 要解決死

24、鎖就要對線程共享的資源做同步控制。 在同步控制中正確的使用sleep()、wait()方法和notify()、 notifyAll()方法。47sleep(),wait()方法 線程調(diào)用了sleep()方法,當前線程進入睡眠,但不會釋放所占用資源對象的鎖。在sleep 時間間隔期滿后,線程不一定立即恢復執(zhí)行(其它線程可能沒執(zhí)行完)。sleep()是線程的靜態(tài)方法 線程調(diào)用了它所占用資源對象的wait()時,使當前線程進入等待隊列,同時釋放所占用資源對象的鎖。直到其他線程調(diào)用此資源對象上的 notify() 方法或notifyAll() 方法時所有等待資源對象的線程被喚醒。wait()是Obje

25、ct對象的方法,不是線程的方法wait()只能在同步方法或同步代碼塊中使用wait()方法和notify()、notifyAll()方法總是配對使用48notity(),notifyAll()方法 notity():隨機喚醒一個想要獲對象鎖的處于等待狀態(tài)的線程來執(zhí)行。 notifyAll():喚醒所有處于等待狀態(tài)的線程。調(diào)用notifyAll()方法并不會立即激活某個等待線程。它只能撤銷等待線程的中斷狀態(tài),這樣它們就能夠在當前線程退出synchronized方法后,與其它線程展開競爭,以爭取獲得資源對象來執(zhí)行。49線程的死鎖3-1public class DeadLockThread/創(chuàng)建兩個

26、線程之間競爭使用的對象private static Object lock1 = new Object();private static Object lock2 = new Object();public static void main(String args)new Thread(new ShareThread1().start();new Thread(new ShareThread2().start();50線程的死鎖3-2private static class ShareThread1 implements Runnablepublic void run()synchronize

27、d(lock1)tryThread.sleep(50);catch(InterruptedException e)e.printStackTrace();synchronized(lock2) System.out.println(ShareThread1);51線程的死鎖3-3private static class ShareThread2 implements Runnablepublic void run()synchronized(lock2)tryThread.sleep(50);catch(InterruptedException e)e.printStackTrace();sy

28、nchronized(lock1) System.out.println(ShareThread2);52線程的協(xié)作 Java提供了wait()、notify()、notifyAll()三個方法,解決線程之間協(xié)作的問題。這三個方法均是java.lang.Object類的方法,都只能在同步方法或者同步代碼塊中使用,否則會拋出異常。void wait():當前線程等待,等待其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法將其喚醒。void notify():喚醒在此對象鎖上等待的單個線程。void notifyAll():喚醒在此對象鎖上等待的所有線程。53線程的協(xié)作5

29、-1 需求定義一個集合模擬長條容器存放熱狗,集合里實際存放Integer,其值代表熱狗的編號(熱狗編號規(guī)則舉例:300002代表編號為3的廚師做的第2個熱狗),這樣能通過集合添加和刪除,實現(xiàn)先進先出;以熱狗集合作為對象鎖,所有對熱狗集合的操作(在長條容器中添加、取走熱狗)互斥,這樣保證不會出現(xiàn)多個顧客同時取最后剩下的一個熱狗的情況,也不會出現(xiàn)多個廚師同時添加熱狗造成長條容器里熱狗數(shù)大于10個的情況;當廚師希望往長條容器中添加熱狗時,如果發(fā)現(xiàn)長條容器中已有10個熱狗,則停止做熱狗,等待顧客從長條容器中取走熱狗的事件發(fā)生,以喚醒廚師可以重新進行判斷,是否需要做熱狗;當顧客希望往長條容器中取走熱狗時

30、,如果發(fā)現(xiàn)長條容器中已沒有熱狗,則停止吃熱狗,等待廚師往長條容器中添加熱狗的事件發(fā)生,以喚醒顧客可以重新進行判斷,是否可以取走熱狗吃;54線程的協(xié)作5-2 線程的協(xié)作import java.util.*;public class TestProdCons /定義一個存放熱狗的集合,里面存放的是整數(shù),代表熱狗編號 private static final List hotDogs = new ArrayList(); public static void main(String args)for(int i = 1;i = 3;i+) new Producer(i).start();for(int i = 1;i = 5;i+) new Consumer(i).start();try Thread.sleep(2000);catch(InterruptedException e) e.printStackTrace();System.exit(0); 55線程的協(xié)作5-3/生產(chǎn)者線程,以熱狗集合作為對象鎖,所有對熱狗集合的操作互斥 private static class Producer extends Threadint i = 1;int pid = -1;pu

溫馨提示

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

評論

0/150

提交評論