chap11多線程
《chap11多線程》由會(huì)員分享,可在線閱讀,更多相關(guān)《chap11多線程(52頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、單擊此處編輯母版標(biāo)題樣式,,單擊此處編輯母版文本樣式,,*,,*,1,第,11,章 多線程,本章主要講述如下內(nèi)容:,,?,多線程的概念;,,?,線程的生命周期;,,?,多線程編程中的常量和方法;,,?,線程調(diào)度方法;,,?,資源沖突與協(xié)調(diào);,,?,線程之間的通信。,2,11,.1,Java,中多線程的基本概念,,在多線程模型中,多個(gè)線程共存于同一塊內(nèi)存中,且共享資源。,,每個(gè)線程分配有限的時(shí)間片來(lái)處理任務(wù)。由于,CPU,在各個(gè)線程之間的切換速度非??欤脩?hù)感覺(jué)不到,從而認(rèn)為并行運(yùn)行。,,3,11,.1.1 多線程的特點(diǎn),多個(gè)線程在運(yùn)行時(shí),系統(tǒng)自動(dòng)在線程之間進(jìn)行切換;,,由于多個(gè)線程共存于
2、同一塊內(nèi)存,線程之間的通信非常容易;,,Java,將線程視為一個(gè)對(duì)象。線程要么是,Thread,類(lèi)的對(duì)象,要么是接口,Runnable,的對(duì)象。,4,11,.1.1 多線程的特點(diǎn)(續(xù)),當(dāng)多個(gè)線程并行執(zhí)行時(shí),具有較高優(yōu)先級(jí)的線程將獲得較多的,CPU,時(shí)間片;,,優(yōu)先級(jí)是從0到10的整數(shù),并且它僅表示線程之間的相對(duì)關(guān)系;,,多個(gè)線程共享一組資源,有可能在運(yùn)行時(shí)產(chǎn)生沖突。必須采用,synchronized,關(guān)鍵字協(xié)調(diào)資源,實(shí)現(xiàn)線程同步。,5,9.2.1 多線程編程中常用的常量和方法,線程類(lèi),Thread,定義在,java.lang,包中;,,Thread,類(lèi)包含的常量有:,1.,public
3、 static final int MAX_PRIORITY:,最大優(yōu)先級(jí),值是10。,,2.,public static final int MIN_PRIORITY:,最小優(yōu)先級(jí),值是1。,,3.,public static final int NORM_PRIORITY:,缺省優(yōu)先級(jí),值是5。,,優(yōu)先級(jí)的定義有部分在不同系統(tǒng)間有差別。,,不要假定高優(yōu)先級(jí)的線程一定先于低優(yōu)先級(jí)的線程執(zhí)行,不要有邏輯依賴(lài)于線程優(yōu)先級(jí),否則可能產(chǎn)生意外結(jié)果,6,7,11,.2.1 多線程編程中常用的常量和方法(續(xù)),常用方法:,currentThread( ):,返回當(dāng)前運(yùn)行的線程對(duì)象,是一個(gè)靜態(tài)的方法。,
4、,sleep(int n):,使當(dāng)前運(yùn)行的線程睡,n,個(gè)毫秒,然后繼續(xù)執(zhí)行,也是靜態(tài)方法。,,yield( ):,使當(dāng)前運(yùn)行的線程放棄執(zhí)行,切換到其它線程,是一個(gè)靜態(tài)方法。,,isAlive( ):,判斷線程是否處于執(zhí)行的狀態(tài),返回值,true,表示處于運(yùn)行狀態(tài),,false,表示已停止。,8,9.2.1 多線程編程中常用的常量和方法(續(xù)),start( ):,使調(diào)用該方法的線程開(kāi)始執(zhí)行。,,run( ):,該方法由,start( ),方法自動(dòng)調(diào)用。,,stop( ):,使線程停止執(zhí)行,并退出可執(zhí)行狀態(tài)。,,suspend():,使線程暫停執(zhí)行,不退出可執(zhí)行態(tài)。,,resume( ):,將暫
5、停的線程繼續(xù)執(zhí)行。,,setName(String s):,賦予線程一個(gè)名字。,,getName( ):,獲得調(diào)用線程的名字。,9,11,.2.1 多線程編程中常用的常量和方法(續(xù)),getPriority( ):,獲得調(diào)用線程的優(yōu)先級(jí)。,,setPriority(int p):,設(shè)置線程的優(yōu)先級(jí)。,,join( ):,等待線程死亡,若中斷了該線程, 將拋出異常。,10,11,.2.1 多線程編程中常用的常量和方法(續(xù)),注意1:在創(chuàng)建線程對(duì)象時(shí),缺省的線程優(yōu)先級(jí)是,5,,一般設(shè)置優(yōu)先級(jí),4,到,6,之間,不要設(shè)置為,10,,否則其它線程將執(zhí)行不到。,,注意2:,
6、Java,的調(diào)度器能使高優(yōu)先級(jí)的線程始終運(yùn)行,一旦,CPU,有空閑,具有同等優(yōu)先級(jí)的線程,以輪流的方式順序使用時(shí)間片。,,11,11,.2.2,線程的生命周期,,,,,,,,,,,,class getThreadInfo {,// 程序1:?jiǎn)尉€程示例,,public static void main(String args[ ]) {,,String name;,,int p;,,Thread curr;,,,,,curr=Thread.currentThread( );,,,System.out.println(",當(dāng)前線程: "+,curr);,,name=curr.getName( );
7、,,,p=curr.getPriority( );,,,System.out.println(",線程名: "+,name);,,System.out.println(",優(yōu)先級(jí) :"+,p);,,},,},程序輸出結(jié)果:,,當(dāng)前線程:,Thread[main,5,main],,線程名 :,main,,優(yōu)先級(jí),:5,14,11,.2.3,創(chuàng)建多線程的方法,,,方法1:通過(guò),Thread,類(lèi)的子類(lèi)實(shí)現(xiàn)多線程。,,,方法2:定義一個(gè)實(shí)現(xiàn),Runnable,接口的類(lèi)實(shí)現(xiàn)多線程。,,15,11,.2.3,創(chuàng)建多線程的方法(續(xù)),方法1:通過(guò)創(chuàng)建,Thread,類(lèi)的子類(lèi)實(shí)現(xiàn)多線程,步驟如下,:,1. 定
8、義,Thread,類(lèi)的一個(gè)子類(lèi)。,,2. 定義子類(lèi)中的方法,run( ),,覆蓋父類(lèi)中的 方法,run( )。,,3.,創(chuàng)建該子類(lèi)的一個(gè)線程對(duì)象。,,4. 通過(guò),start( ),方法啟動(dòng)線程。例如:,// 程序2,,class UserThread extends Thread{,,int sleepTime;,,,public UserThread(String id) { //,構(gòu)造方法,,super(id);,,,sleepTime=(int)(Math.random( )*1000);,,System.out.println(",線程名: "+,getName( )+
9、,,",,睡眠: "+,sleepTime+",毫秒");,,},,public void run( ) {,,try{ //,通過(guò)線程睡眠模擬程序的執(zhí)行,,,Thread.sleep(sleepTime);,,}catch(InterruptedException e) {,,System.err.println(",運(yùn)行異常:,",+,,e.toString( ));,,},,,System.out.println(",運(yùn)行的線程是:"+,,getName( ));,,},,},public class multThreadTest{,,public static void main(S
10、tring args[ ]) {,,UserThread t1,t2,t3,t4;,,,t1=new UserThread("NO 1");,,t2=new UserThread("NO 2");,,t3=new UserThread("NO 3");,,t4=new UserThread("NO 4");,,t1.start( ); t2.start( );,,t3.start( ); t4.start( );,,},,},程序某次的運(yùn)行結(jié)果:,,線程名:,NO 1,,睡眠: 885 毫秒,,線程名:,NO 2,,睡眠: 66 毫秒,,線程名:,NO 3,,睡眠: 203 毫秒,,線程名
11、:,NO 4,,睡眠: 294 毫秒,,目前運(yùn)行的線程是:,NO 2,,目前運(yùn)行的線程是:,NO 3,,目前運(yùn)行的線程是:,NO 4,,目前運(yùn)行的線程是:,NO 1,注意:,Thread,類(lèi)中的,run( ),方法具有,public,屬性,覆蓋該方法時(shí),前面必須帶上,public。,20,11,.2.3,創(chuàng)建多線程的方法(續(xù)),方法2:通過(guò)接口創(chuàng)建多線程,步驟如下:,1.,定義一個(gè)實(shí)現(xiàn),Runnable,接口的類(lèi)。,,,2.,定義方法,run( ),。,Runnable,接口中有一個(gè)空的方法,run( ),,,實(shí)現(xiàn)它的類(lèi)必須覆蓋此方法。,,,3.,創(chuàng)建該類(lèi)的一個(gè)線程對(duì)象,并將該對(duì)象作參數(shù),傳遞
12、給,Thread,類(lèi)的構(gòu)造函數(shù),從而生成,Thread,類(lèi)的一個(gè)對(duì)象。,// 注意這一步!,,4.通過(guò),start( ),方法啟動(dòng)線程。例如3:,// 程序3,,class UserMultThread implements Runnable{,,int num;,,UserMultThread(int n) {,,num=n;,,},,,public void run( ) {,,for(int i=0;i<3;i++),,System.out.println(",運(yùn)行線程:"+,num);,,,System.out.println(",結(jié)束 : "+,num);,,},,},public
13、class multThreadZero {,,public static void main(String args[ ]),,throws InterruptedException {,,Thread mt1=new Thread(,,new UserMultThread(1));,,Thread mt2=new Thread(,,new UserMultThread(2));,,,mt1.start( );,,mt2.start( );,,mt1.join( ); //,等待線程死亡,,,mt2.join( );,,},,},程序運(yùn)行某次的輸出結(jié)果:,,運(yùn)行線程:1,,運(yùn)行
14、線程:2,,運(yùn)行線程:1,,運(yùn)行線程:2,,運(yùn)行線程:1,,運(yùn)行線程:2,,結(jié)束 : 1,,結(jié)束 : 2,24,11,.2.3,創(chuàng)建多線程的方法(續(xù)),程序3中需要注意的2點(diǎn):,,1.,mt1.join( ),是等待線程死亡,對(duì)該方法必須捕捉異常,或通過(guò),throws,關(guān)鍵字指明可能要發(fā)生的異常。,,2. 對(duì)一個(gè)線程不能調(diào)用,start( ),兩次,否則會(huì)產(chǎn)生,IllegalThreadStateException,異常,。,25,11,.3.1,線程調(diào)度模型,,線程調(diào)度程序挑選線程時(shí),將選擇處于就緒狀態(tài)且優(yōu)先級(jí)最高的線程。,,如果多個(gè)線程具有相同的優(yōu)先級(jí),它們將被輪流調(diào)度。,,程序,4,驗(yàn)證
15、了,Java,對(duì)多線程的調(diào)度方法。,,class threadTest extends Thread{,// 程序4,,threadTest(String str){ super(str); },,,,public void run( ){,,try{,,Thread.sleep(2);,,}catch(InterruptedException e) {,,System.err.println(e.toString( ));,,},,,System.out.println(getName( )+" " +,,getPriority( ));,,},,},public class multThe
16、adOne{,,public static void main(String agrs[]){,,Thread one=new threadTest("one" );,,Thread two=new threadTest("two" );,,Thread three=new threadTest("three" );,,,,one.setPriority(Thread.MIN_PRIORITY);,,two.setPriority(Thread.NORM_PRIORITY);,,three.setPriority(Thread.MAX_PRIORITY);,,,,one.start( );,,
17、two.start( );,,three.start( );,,},,},程序輸出結(jié)果:,,three 10,,two 5,,one 1,29,11,.3.2,資源沖突,,多個(gè)線程同時(shí)運(yùn)行雖然可以提高程序的執(zhí)行效率,但由于共享一組資源,可能會(huì)產(chǎn)生沖突,例如程序5 。,,class UserThread{ //,程序5,,void Play(int n) {,,System.out.println(",運(yùn)行線程,NO:"+n);,,,try{,,Thread.sleep(3);,,}catch(InterruptedException e) {,,System.out.println
18、(“,線程異常,,NO:"+n);,,},,,System.out.println(",結(jié)束線程,NO:"+n);,,},,},class UserMultThread implements Runnable{,,UserThread UserObj;,,int num;,,,UserMultThread(UserThread o,int n) {,,UserObj=o;,,num=n;,,},,,public void run( ) {,,UserObj.Play(num);,,},,},public class multTheadTwo {,,public static void main
19、(String args[ ]) {,,UserThread Obj=new UserThread( );,,Thread t1=new Thread(,,new UserMultThread(Obj,1));,,,Thread t2=new Thread(,,new UserMultThread(Obj,2));,,Thread t3=new Thread(,,new UserMultThread(Obj,3));,,,t1.start( ); t2.start( ); t3.start( );,,},,},程序輸出結(jié)果:,,運(yùn)行線程,NO:1,,運(yùn)行線程,NO:3,,結(jié)束線程,NO:1,,
20、結(jié)束線程,NO:3,,運(yùn)行線程,NO:2,,結(jié)束線程,NO:2,34,11,.3.3,同步方法,,Java,通過(guò)關(guān)鍵字,synchronized,實(shí)現(xiàn)同步。,,當(dāng)對(duì)一個(gè)對(duì)象(含方法)使用,synchronized,,這個(gè)對(duì)象便被鎖定或者說(shuō)進(jìn)入了監(jiān)視器,。,在一個(gè)時(shí)刻只能有一個(gè)線程可以訪問(wèn)被鎖定的對(duì)象。它訪問(wèn)結(jié)束時(shí),讓高優(yōu)先級(jí)并處于就緒狀態(tài)的線程,繼續(xù)訪問(wèn)被鎖定的對(duì)象,,,從而實(shí)現(xiàn)資源同步。,,,加鎖的方法有兩種:鎖定沖突的對(duì)象,或鎖定沖突的方法。,,35,11,.3.3,同步方法(續(xù)),1.,鎖定沖突的對(duì)象,。語(yǔ)法格式:,synchronized ( ObjRef ){,,Block
21、 //,需要同步執(zhí)行的語(yǔ)句體,,},,,,鎖定對(duì)象可以出現(xiàn)在任何一個(gè)方法中。例如,修改程序5中的方法,run( ),如下:,public void run( ) {,,synchronized(UserObj) {,,,UserObj.Play(num);,,},,},,,,運(yùn)行結(jié)果如下:,,運(yùn)行線程,NO:1,,結(jié)束線程,NO:1,,運(yùn)行線程,NO:2,,結(jié)束線程,NO:2,,運(yùn)行線程,NO:3,,結(jié)束線程,NO:3,37,11,.3.3,同步方法(續(xù)),2.,鎖定沖突的方法,。語(yǔ)法格式:,,synchronized,方法的定義,,,例如,修改程序9-5中的方法,Play,( ),如下:,
22、,synchronized void Play(int n) {,,…… //,中間的程序代碼略,,},,注意:,,1.,對(duì)方法,run( ),無(wú)法加鎖,不可避免沖突;,,,2.,對(duì)構(gòu)造函數(shù)不能加鎖,否則出現(xiàn)語(yǔ)法錯(cuò)誤。,,38,11,.4,線程間通信,,多線程通信的方法有兩種:,,1. 把共享變量和方法封裝在一個(gè)類(lèi)中實(shí)現(xiàn);,,2. 通過(guò),wait( ),和,notify( ),方法實(shí)現(xiàn)。,39,11,.4.1,通過(guò)封裝共享變量實(shí)現(xiàn)線程通信,,程序6演示了通過(guò)將共享變量封裝在一個(gè)類(lèi)中,實(shí)現(xiàn)線程通信,class comm{ //,共享類(lèi),,,private int n;,,priva
23、te boolean bool=false;,,void produce(int i) {,,while(bool) { },,n=i;,,bool=true;,,System.out.println("\n,產(chǎn)生數(shù)據(jù):"+,n);,,},,void readout( ) {,,while(!bool) { },,bool=false;,,System.out.println(",讀取數(shù)據(jù):"+,n);,,},,},//,讀取數(shù)據(jù)類(lèi),,class dataProducer implements Runnable{,,,comm cm;,,dataProducer(comm c) {
24、,,,cm=c;,,},,public void run( ) { //,生產(chǎn)者產(chǎn)生5個(gè)隨機(jī)數(shù),,,for(int i=0;i<5;i++),,cm.produce((int)(Math.random( )*100));,,},,},class dataConsumer implements Runnable{,,comm cm;,,dataConsumer(comm c) {,,cm=c;,,},,public void run( ) {,,for(int i=0;i<5;i++) cm.readout( ); //,消費(fèi)者讀取數(shù)據(jù),,},,},public cl
25、ass multTheadThree {,,public static void main(String args[ ]) {,,comm cm=new comm( );,,,,Thread t1=new Thread( //,無(wú)名對(duì)象做參數(shù),,new dataProducer(cm));,,,Thread t2=new Thread(,,new dataConsumer(cm));,,,,t1.start( );,,t2.start( );,,},,},程序的某次運(yùn)行結(jié)果:,,產(chǎn)生數(shù)據(jù):81,,讀取數(shù)據(jù):81,,產(chǎn)生數(shù)據(jù):15,,讀取數(shù)據(jù):15,,產(chǎn)生數(shù)據(jù):92,,讀取數(shù)據(jù):92,,產(chǎn)生數(shù)據(jù)
26、:98,,讀取數(shù)據(jù):98,,產(chǎn)生數(shù)據(jù):79,,讀取數(shù)據(jù):79,45,11,.4.2,通過(guò)系統(tǒng)方法實(shí)現(xiàn)線程通信,,線程同步控制的第二種方法是采用如下幾個(gè)系統(tǒng)方法:,,1.wait( ),方法:使一個(gè)線程進(jìn)入等待狀態(tài),直到被喚醒。,,2.,notify( ),方法:通知等待監(jiān)視器的線程,該對(duì)象的狀態(tài)已經(jīng)發(fā)生了改變。,,3.,notifyAll( ),方法:?jiǎn)拘褟耐粋€(gè)監(jiān)視器中用,wait( ),方法退出的所有線程,使它們按照優(yōu)先級(jí)的順序重新排隊(duì)。例如,程序,7。,class comm{,// 程序7,,private int n;,,private boolean bool=false;,,syn
27、chronized void produce(int i) {,,if(bool) {,,try{,,wait( );,,}catch(InterruptedException e) {,,System.out.println("comm,出現(xiàn)異常");,,},,},else{,,n=i;,,bool=true;,,System.out.println("\n,產(chǎn)生數(shù)據(jù): "+,n);,,notify( ); //,喚醒另外一個(gè)線程,,},,},synchronized void readout( ) {,,if(!bool) {,,try{,,wait( );,,}catch(Inter
28、ruptedException e) {,,System.out.println(" comm,出現(xiàn)異常");,,},,},else{,,bool=false;,,System.out.println(",讀取數(shù)據(jù): "+,n);,,notify( ); //,喚醒另一個(gè)線程,,},,},,},class dataProducer implements Runnable{,,comm cm;,,dataProducer (comm c) { cm=c; },,,public void run( ) {,,try{,,for(int i=0;i<5;i++) {,,cm.produc
29、e((int)(Math.random( )*100));,,Thread.sleep(10);,,},,},catch(InterruptedException e) {,,System.out.println("dataProducer,出現(xiàn)異常");,,},,},,},class dataConsumer implements Runnable{,,comm cm;,,dataConsumer(comm c) { cm=c; },,,public void run( ) {,,try{,,for(int i=0;i<5;i++) {,,cm.readout( );,,Thread.sl
30、eep(10);,,},,}catch(InterruptedException e) {,,System.out.println(" dataConsumer,出現(xiàn)異常");,,},,},,},public class multTheadFour{,,public static void main(String args[ ]) {,,comm cm=new comm( );,,Thread t1=new Thread(new dataProducer (cm));,,Thread t2=new Thread(new dataConsumer(cm));,,,t1.start( );,,t2
31、.start( );,,},,},程序輸出結(jié)果:,,產(chǎn)生數(shù)據(jù): 90,,讀取數(shù)據(jù): 90,,,產(chǎn)生數(shù)據(jù): 10,,讀取數(shù)據(jù): 10,,,產(chǎn)生數(shù)據(jù): 65,,讀取數(shù)據(jù): 65,,,產(chǎn)生數(shù)據(jù): 45,,讀取數(shù)據(jù): 45,52,線程調(diào)度建議,線程進(jìn)入等待隊(duì)列的方式有:一、線程,a,正在使用某對(duì)象,線程,b,調(diào)用該對(duì)象的同步方法,則,b,進(jìn)入隊(duì)列;二、調(diào)用,wait( ),方法使線程進(jìn)入隊(duì)列。,,,當(dāng)一個(gè)同步方法調(diào)用返回時(shí),或一個(gè)方法調(diào)用了,wait( ),方法時(shí),另一線程就可訪問(wèn)沖突的對(duì)象。,,,線程調(diào)度程序在隊(duì)列中選取優(yōu)先級(jí)最高的線程。,,如果一個(gè)線程因調(diào)用,wait( ),而進(jìn)入隊(duì)列,則必須調(diào)用,notify( ),才能,“,解凍,”,該線程。,,
- 溫馨提示:
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. 裝配圖網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 房地產(chǎn)銷(xiāo)售工作總結(jié)區(qū)域績(jī)效完成情況明年工作計(jì)劃
- 人資部部門(mén)年終總結(jié)人力資源規(guī)劃與實(shí)施
- 教師課程總結(jié)匯報(bào)提升教學(xué)質(zhì)量與反思教學(xué)過(guò)程
- 2025年中小學(xué)校黨建工作計(jì)劃2篇例文
- 2025年學(xué)校黨建工作計(jì)劃(工作要點(diǎn))5篇范文
- 2025年學(xué)校黨建工作計(jì)劃例文【3份】
- 初中英語(yǔ)知識(shí)點(diǎn)總結(jié):英語(yǔ)副詞精華講解
- 施工安全事故易發(fā)期
- 安全管理人員安全工作總結(jié)范文
- 初中英語(yǔ)重點(diǎn)語(yǔ)法:三大從句總結(jié)
- 鐵路廣場(chǎng)冰雪等極端天氣的安全應(yīng)急預(yù)案
- 安全培訓(xùn)資料:某公司職業(yè)病防治宣傳教育培訓(xùn)制度
- 初中英語(yǔ)最齊全的8大時(shí)態(tài)
- 硝酸使用安全和典型案例、對(duì)策
- 安全培訓(xùn)資料:某公司職業(yè)病危害事故處置與報(bào)告制度