- 相關(guān)推薦
Java多線(xiàn)程知識(shí)點(diǎn)
引導(dǎo)語(yǔ);多線(xiàn)程是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線(xiàn)程并發(fā)執(zhí)行的技術(shù)。以下是百分網(wǎng)小編分享給大家的Java多線(xiàn)程知識(shí)點(diǎn),歡迎閱讀!
1.1多線(xiàn)程的概念
多線(xiàn)程編程的含義是你可將程序任務(wù)分成幾個(gè)并行的子任務(wù)。特別是在網(wǎng)絡(luò)編程中,你會(huì)發(fā)現(xiàn)很多功能是可以并發(fā)執(zhí)行的。比如網(wǎng)絡(luò)傳輸速度較慢,用戶(hù)輸入速度較慢,你可以用兩個(gè)獨(dú)立的線(xiàn)程去完成這?copy;功能,而不影響正常的顯示或其他功能。多線(xiàn)程是與單線(xiàn)程比較而言的,普通的WINDOWS采用單線(xiàn)程程序結(jié)構(gòu),其工作原理是:主程序有一個(gè)消息循環(huán),不斷從消息隊(duì)列中讀入消息來(lái)決定下一步所要干的事情,一般是一個(gè)子函數(shù),只有等這個(gè)子函數(shù)執(zhí)行完返回后,主程序才能接收另外的消息來(lái)執(zhí)行。比如子函數(shù)功能是在讀一個(gè)網(wǎng)絡(luò)數(shù)據(jù),或讀一個(gè)文件,只有等讀完這?copy;數(shù)據(jù)或文件才能接收下一個(gè)消息。在執(zhí)行這個(gè)子函數(shù)過(guò)程中你什么也不能干。但往往讀網(wǎng)絡(luò)數(shù)據(jù)和等待用戶(hù)輸入有很多時(shí)間處于等待狀態(tài),多線(xiàn)程利用這個(gè)特點(diǎn)將任務(wù)分成多個(gè)并發(fā)任務(wù)后,就可以解決這個(gè)問(wèn)題。
1.1.1Java線(xiàn)程的模型
Java的設(shè)計(jì)思想是建立在當(dāng)前大多數(shù)操作系統(tǒng)都實(shí)現(xiàn)了線(xiàn)程調(diào)度。Java虛擬機(jī)的很多任務(wù)都依賴(lài)線(xiàn)程調(diào)度,而且所有的類(lèi)庫(kù)都是為多線(xiàn)程設(shè)計(jì)的。實(shí)時(shí)上,Java支持Macintosh和Ms-dos的平臺(tái)?reg;所以遲遲未出來(lái)就是因?yàn)檫@兩個(gè)平臺(tái)都不支持多線(xiàn)程。Java利用多線(xiàn)程實(shí)現(xiàn)了整個(gè)執(zhí)行環(huán)境是異步的。在Java程序里沒(méi)有主消息循環(huán)。如果一個(gè)線(xiàn)程等待讀取網(wǎng)絡(luò)數(shù)據(jù),它可以運(yùn)行但不停止系統(tǒng)的其他線(xiàn)程執(zhí)行。用于處理用戶(hù)輸入的線(xiàn)程大多時(shí)間是等待用戶(hù)敲鍵盤(pán)或擊鼠標(biāo)。你還可以使動(dòng)畫(huà)的每一幀?reg;間停頓一秒而并不使系統(tǒng)暫停。一?copy;線(xiàn)程啟動(dòng)后,它可以被掛起,暫時(shí)不讓它執(zhí)行。掛起的線(xiàn)程可以重新恢復(fù)執(zhí)行。任何時(shí)間線(xiàn)程都可以被停止,被停止的線(xiàn)程就不能再重新啟動(dòng)。Java語(yǔ)言里,線(xiàn)程表現(xiàn)為線(xiàn)程類(lèi),線(xiàn)程類(lèi)封裝了所有需要的線(xiàn)程操作控制。在你心里,必須很清晰地區(qū)分開(kāi)線(xiàn)程對(duì)象和運(yùn)行線(xiàn)程,你可以將線(xiàn)程對(duì)象看作是運(yùn)行線(xiàn)程的控制面板。在線(xiàn)程對(duì)象里有很多函數(shù)來(lái)控制一個(gè)線(xiàn)程是否運(yùn)行,睡眠,掛起或停止。線(xiàn)程類(lèi)是控制線(xiàn)程行為的唯一的手段。一?copy;一個(gè)Java程序啟動(dòng)后,就已經(jīng)有一個(gè)線(xiàn)程在運(yùn)行。你可通過(guò)調(diào)用Thread.currentThread函數(shù)來(lái)查看當(dāng)前運(yùn)行的是哪一個(gè)線(xiàn)程。
你得到一個(gè)線(xiàn)程的控制柄,你就可以作很有趣的事情,即使單線(xiàn)程也一樣。下面這個(gè)例子讓你知道怎樣操縱當(dāng)前線(xiàn)程。Filename:testthread
classtestthread{publicstaticvoidmain(Stringargs[]){Threadt
=Thread.currentThread();t.setName(\"ThisThreadisrunning\");
System.out.println(\"Therunningthread:\"+t);try{for(inti=0;i
{System.out.println(\"Sleeptime\"+i);Thread.sleep(1000);}
}catch(InterruptedExceptione){System.out.println(\"threadhaswrong\");}
}}
執(zhí)行結(jié)果:javatestthreadTherunningthread:Thread[ThisThreadisrunning,5,main]Sleeptime0Sleeptime1Sleeptime2Sleeptime3Sleeptime4
1.1.2啟動(dòng)接口
一個(gè)線(xiàn)程并不激動(dòng)人心,多個(gè)線(xiàn)程才有實(shí)際意義。我們?cè)鯓觿?chuàng)建更多的線(xiàn)程呢?我們需要?jiǎng)?chuàng)建線(xiàn)程類(lèi)的另一個(gè)實(shí)例。當(dāng)我們構(gòu)造了線(xiàn)程類(lèi)的一個(gè)新的實(shí)例,我們必須告訴它在新的線(xiàn)程里應(yīng)執(zhí)行哪一段程序。你可以在任意實(shí)現(xiàn)了啟動(dòng)接口的對(duì)象上啟動(dòng)一個(gè)線(xiàn)程。啟動(dòng)接口是一個(gè)抽象接口,來(lái)表示本對(duì)象有一?copy;函數(shù)想異步執(zhí)行。要實(shí)現(xiàn)啟動(dòng)接口,一個(gè)類(lèi)只需要有一個(gè)叫run的函數(shù)。下面是創(chuàng)建一個(gè)新線(xiàn)程的例子:
Filename:twothread.java
classtwothreadimplementsRunnable{twothread(){Threadt1
=Thread.currentThread();t1.setName(\"Thefirstmainthread\");
System.out.println(\"Therunningthread:\"+t1);Threadt2=new
Thread(this,\"thesecondthread\");System.out.println(\"creatanother
thread\");t2.start();try{System.out.println(\"firstthreadwill
sleep\");Thread.sleep(3000);}catch(InterruptedExceptione)
{System.out.println(\"firstthreadhaswrong\");}
System.out.println(\"firstthreadexit\");}publicvoidrun(){try{for
(inti=0;i
Thread.sleep(1000);}
}catch(InterruptedExceptione){System.out.println(\"threadhas
wrong\");}
System.out.println(\"secondthreadexit\");}publicstaticvoid
main(Stringargs[]){newtwothread();}}
執(zhí)行結(jié)果:javatwothread
Therunningthread:Thread[Thefirstmainthread,5,main]creatanother
threadfirstthreadwillsleepSleeptimeforthread2:0Sleeptimefor
thread2:1Sleeptimeforthread2:2firstthreadexitSleeptimefor
thread2:3Sleeptimeforthread2:4secondthreadexit
main線(xiàn)程用newThread(this,\"thesecondthread\")創(chuàng)建了一個(gè)Thread對(duì)象,通過(guò)傳遞第一個(gè)參數(shù)來(lái)標(biāo)明新線(xiàn)程來(lái)調(diào)用this對(duì)象的run函數(shù)。然后我們調(diào)用start函數(shù),它將使線(xiàn)程從run函數(shù)開(kāi)始執(zhí)行。
1.1.3同步
因?yàn)槎嗑(xiàn)程給你提?copy;了程序的異步執(zhí)行的功能,所以在必要時(shí)必須還提?copy;一種同步機(jī)制。例如,你想兩個(gè)線(xiàn)程通訊并共享一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu),你需要一種機(jī)制讓他們相互牽制并正確執(zhí)行。為這個(gè)目的,Java用一種叫監(jiān)視器(monitor)的機(jī)制實(shí)現(xiàn)了進(jìn)程間的異步執(zhí)行?梢詫⒈O(jiān)視器看作是一個(gè)很小的盒子,它只能容納一個(gè)線(xiàn)程。一?copy;一個(gè)線(xiàn)程進(jìn)入一個(gè)監(jiān)視器,所有其他線(xiàn)程必須等到第一個(gè)線(xiàn)程退出監(jiān)視器后才能進(jìn)入。這?copy;監(jiān)視器可以設(shè)計(jì)成保護(hù)共享的數(shù)據(jù)不被多個(gè)線(xiàn)程同時(shí)操作。大多數(shù)多線(xiàn)程系統(tǒng)將這?copy;監(jiān)視器設(shè)計(jì)成對(duì)象,Java提?copy;了一種更清晰的解決方案。沒(méi)有Monitor類(lèi);每個(gè)對(duì)象通過(guò)將他們的成員函數(shù)定義成synchronized來(lái)定義自己的顯式監(jiān)視器,一?copy;一個(gè)線(xiàn)程執(zhí)行在一個(gè)synchronized函數(shù)里,其他任何線(xiàn)程都不能調(diào)用同一個(gè)對(duì)象的
synchronized函數(shù)。
1.1.4消息
你的程序被分成幾個(gè)邏輯線(xiàn)程,你必須清晰的知道這?copy;線(xiàn)程?reg;間應(yīng)怎樣相互通訊。Java提了wait和notify等功能來(lái)使線(xiàn)程?reg;間相互交談。一個(gè)線(xiàn)程可以進(jìn)入某一個(gè)對(duì)象的synchronized函數(shù)進(jìn)入等待狀態(tài),直到其他線(xiàn)程顯式地將它喚醒?梢杂卸鄠(gè)線(xiàn)程進(jìn)入同一個(gè)函數(shù)并等待同一個(gè)喚醒消息。
1.2Java線(xiàn)程例子
1.2.1顯式定義線(xiàn)程
在我們的單線(xiàn)程應(yīng)用程序里,我們并沒(méi)有看見(jiàn)線(xiàn)程,因?yàn)镴ava能自動(dòng)創(chuàng)建和控制你的線(xiàn)程。如果你使用了理解Java語(yǔ)言的瀏覽器,你就已經(jīng)看到使用多線(xiàn)程的Java程序了。你也許注意到兩個(gè)小程序可以同時(shí)運(yùn)行,或在你移動(dòng)滾動(dòng)條時(shí)小程序繼續(xù)執(zhí)行。這并不是表明小程序是多線(xiàn)程的,但說(shuō)明這個(gè)瀏覽器是多線(xiàn)程的。多線(xiàn)程應(yīng)用程序(或applet)可以使用好幾個(gè)執(zhí)行上下文來(lái)完成它們的工
作。多線(xiàn)程利用了很多任務(wù)包含單獨(dú)的可分離的子任務(wù)的特點(diǎn)。每一個(gè)線(xiàn)程完成一個(gè)子任務(wù)。但是,每一個(gè)線(xiàn)程完成子任務(wù)時(shí)還是順序執(zhí)行的。一個(gè)多線(xiàn)程程序允許各個(gè)線(xiàn)程盡快執(zhí)行完它們。這種特點(diǎn)會(huì)有更好的實(shí)時(shí)輸入反應(yīng)。
1.2.2多線(xiàn)程例子
下面這個(gè)例子創(chuàng)建了三個(gè)單獨(dú)的線(xiàn)程,它們分別打印自己的\"HelloWorld\":
//Defineoursimplethreads.Theywillpauseforashorttime//andthen
printouttheirnamesanddelaytimesclassTestThreadextendsThread
{privateStringwhoami;privateintdelay;
//Ourconstructortostorethename(whoami)//andtimetosleep(delay)
publicTestThread(Strings,intd){whoami=s;delay=d;}
//Run-thethreadmethodsimilartomain()//Whenrunisfinished,the
threaddies.//Runiscalledfromthestart()methodofThreadpublicvoid
run(){//Trytosleepforthespecifiedtimetry{sleep(delay);}
catch(InterruptedExceptione){}//Nowprintoutourname
System.out.println(\"HelloWorld!\"+whoami+\"\"+delay);}}/***Multimtest.
Asimplemultithreadthestprogram*/publicclassmultitest{public
staticvoidmain(Stringargs[]){TestThreadt1,t2,t3;//Createourtest
threadst1=newTestThread(\"Thread1\",(int)(Math.readom()*2000));t2=
newTestThread(\"Thread2\",(int)(Math.readom()*2000));t3=new
TestThread(\"Thread3\",(int)(Math.readom()*2000));
//Starteachofthethreadst1.start();t2.start();t3.start();}}
1.2.3啟動(dòng)一個(gè)線(xiàn)程
程序啟動(dòng)時(shí)總是調(diào)用main()函數(shù),因此main()是我們創(chuàng)建和啟動(dòng)線(xiàn)程的地方:
t1=newTestThread(\"Thread1\",(int)(Math.readom()*2000));
這一行創(chuàng)建了一個(gè)新的線(xiàn)程。后面的兩個(gè)參數(shù)傳遞了線(xiàn)程的名稱(chēng)和線(xiàn)程在打印信息?reg;前的延時(shí)時(shí)間。因?yàn)槲覀冎苯涌刂凭(xiàn)程,我們必須直接啟動(dòng)它:t1.start();
1.2.4操作線(xiàn)程
如果創(chuàng)建線(xiàn)程正常,t1應(yīng)包含一個(gè)有效的執(zhí)行線(xiàn)程。我們?cè)诰(xiàn)程的run()函數(shù)里控制線(xiàn)程。一?copy;我們進(jìn)入run()函數(shù),我們便可執(zhí)行里面的任何程序。run()好象main()一樣。
run()執(zhí)行完,這個(gè)線(xiàn)程也就結(jié)束了。在這個(gè)例子里,我們?cè)囍舆t一個(gè)隨機(jī)的時(shí)間(通過(guò)參數(shù)傳遞?)sleep(delay);
sleep()函數(shù)只是簡(jiǎn)單地告訴線(xiàn)程休息多少個(gè)毫秒時(shí)間。
如果你想推遲一個(gè)線(xiàn)程的執(zhí)行,你應(yīng)使用sleep()函數(shù)。當(dāng)線(xiàn)程睡眠是sleep()并不占用系統(tǒng)資源。其它線(xiàn)程可繼續(xù)工作。一?copy;延遲時(shí)間完畢,它將打印\"HelloWorld\"和線(xiàn)程名稱(chēng)及延遲時(shí)間。
1.2.5暫停一個(gè)線(xiàn)程
我們經(jīng)常需要掛起一個(gè)線(xiàn)程而不指定多少時(shí)間。例如,如果你創(chuàng)建了一個(gè)含有動(dòng)畫(huà)線(xiàn)程的小程序。也許你讓用戶(hù)暫停動(dòng)畫(huà)至到他們想恢復(fù)為止。你并不想將動(dòng)畫(huà)線(xiàn)程仍調(diào),但想讓它停止。象這種類(lèi)似的線(xiàn)程你可用suspend()函數(shù)來(lái)控制:t1.suspend();這個(gè)函數(shù)并不永久地停止了線(xiàn)程,你還可用resume()函數(shù)重新激活線(xiàn)程:t1.resume();
1.2.6停止一個(gè)線(xiàn)程
線(xiàn)程的最后一個(gè)控制是停止函數(shù)stop()。我們用它來(lái)停止線(xiàn)程的執(zhí)行:t1.stop();
注意:這并沒(méi)有消滅這個(gè)線(xiàn)程,但它停止了線(xiàn)程的執(zhí)行。并且這個(gè)線(xiàn)程不能用t1.start()重新啟動(dòng)。在我們的例子里,我們從來(lái)不用顯式地停止一個(gè)線(xiàn)程。我們只簡(jiǎn)單地讓它執(zhí)行完而已。很多復(fù)雜的線(xiàn)程例子將需要我們控制每一個(gè)線(xiàn)程。在這種情況下會(huì)使用到stop()函數(shù)。如果需要,你可以測(cè)試你的線(xiàn)程是否被激活。一個(gè)線(xiàn)程已經(jīng)啟動(dòng)而且沒(méi)有停止被認(rèn)為是激活的。t1.isAlive()如果t1是激活的,這個(gè)函數(shù)將返回true.
1.2.1動(dòng)畫(huà)例子
下面是一個(gè)包含動(dòng)畫(huà)線(xiàn)程的applet例子:
importjava.awt.*;importjava.awt.image.ImageProducer;import
java.applet.Applet;
publicclassatest3extendsAppletimplementsRunnable{Imageimages[];
MediaTrackertracker;intindex=0;Threadanimator;
intmaxWidth,maxHeight;//Ouroff-screencomponentsfordoublebuffering.
ImageoffScrImage;GraphicsoffScrGC;
//Canwepaintyes?booleanloaded=false;
//Initializetheapplet.Setoursizeandloadtheimagespublicvoidinit()
[//Setupourimagemonitortracker=newMediaTracker(this);
//SetthesizeandwidthofourappletmaxWidth=100;maxHeight=100;
images=newImage[10];//Setupthedouble-bufferandresizeourapplet
try{offScrImage=createImage(maxWidth,maxHeight);offScrGC=
offScrImage.getGraphics();offScrGC.setColor(Color.lightGray);
offScrGC.fillRect(0,0,maxWidth,maxHeight);
resize(maxWidth,maxHeight);}catch(Exceptione)
{e.printStackTrace();}
//loadtheanimationimagesintoanarrayfor(inti=0;i
imageFile=newString(\"images/Duke/T\"+String.valueOf(i+1)+\".gif\");
images[i]=getImage(getDocumentBase(),imageFile)://Registerthis
imagewiththetrackertracker.addImage(images[i],i);}try{//Use
trackertomakesurealltheimagesareloadedtracker.waitForAll();}
catch(InterruptedExceptione){}loaded=true;}
//Paintthecurrentframe.publicvoidpaint(Graphicsg){if(loaded)
{g.drawImage(offScrImage,0,0,this);}}
//Start,setupourfirstimagepublicvoidstart(){if(tracker.checkID
(index)){offScrGC.drawImage(images[index],0,0,this);}animator=new
Thread(this);animator.start();}
//Run,dotheanimationworkhere.//Grabanimage,pause,grabthenext...
publicvoidrun(){//GettheidofthecurrentthreadThreadme=
Thread.currentThread();
//Ifouranimatorthreadexist,andisthecurrentthread...while
((animatr!=null)&&(animator==me)){if(tracker.checkID(index))
{//Clearthebackgroundandgetthenextimage
offScrGC.fillRect(0,0,100,100);
offScrGCdrawImage(images[index],0,0,this);index++;//Loopbacktothe
beginningandkeepgoingif(index>=images.length){index=0;}}
//Delayheresoanimationlooksnormaltry{animator.sleep(200);}catch
(InterruptedExceptione){}//Drawthenextframerepaint();}}}
1.3多線(xiàn)程間的通訊
1.3.1生產(chǎn)者和消費(fèi)者
多線(xiàn)程的一個(gè)重要特點(diǎn)是它們?reg;間可以互相通訊。你可以設(shè)計(jì)線(xiàn)程使用公用對(duì)象,每個(gè)線(xiàn)程都可以獨(dú)立操作公用對(duì)象。典型的線(xiàn)程間通訊建立在生產(chǎn)者和消費(fèi)者模型上:一個(gè)線(xiàn)程產(chǎn)生輸出;另一個(gè)線(xiàn)程使用輸入buffer
讓我們創(chuàng)建一個(gè)簡(jiǎn)單的\"AlphabetSoup\"生產(chǎn)者和相應(yīng)的消費(fèi)者.
1.3.2生產(chǎn)者
生產(chǎn)者將從thread類(lèi)里派生:classProducerextendsThread
{privateSoupsoup;privateStringalphabet=\"
ABCDEFGHIJKLMNOPQRSTUVWXYZ\";
publicProducer(Soups){//Keepourowncopyofthesharedobjectsoup
=s;}
publicvoidrun(){charc;//Throw10lettersintothesoupfor(int
i=0;i
soup.add(c);//printarecordofosraddition
System.out.println(\"Added\"+c+\"tothesoup.\");//waitabitbeforewe
addthenextlettertry{sleep((int)(Math.random()*1000));}catch
(InterruptedExceptione){}}}}
注意我們創(chuàng)建了Soup類(lèi)的一個(gè)實(shí)例。生產(chǎn)者用soup.add()函數(shù)來(lái)建立字符池。
1.3.3消費(fèi)者
讓我們看看消費(fèi)者的程序:classConsumerextendsThread{privateSoupsoup;
publicConsumer(Soups){//keepourowncopyofthesharedobjectsoup
=s;}
publicvoidrun(){charc;//Eat10lettersfromthealphabetsoupfor
(intI=0;i
letterthatweretrievedSystem.out.println(\"Atealetter:\"+c);//try
{sleep((int)(Math.raddom()*2000));}catch(InterruptedExceptione){}}}}
同理,象生產(chǎn)者一樣,我們用soup.eat()來(lái)處理信息。那么,Soup類(lèi)到底干什么呢?
1.3.4監(jiān)視
Soup類(lèi)執(zhí)行監(jiān)視兩個(gè)線(xiàn)程?reg;間傳輸信息的功能。監(jiān)視是多線(xiàn)程中不可缺少的一部分,因?yàn)樗3至送ㄓ嵉牧?copy;。讓我們看看Soup.java文件:classSoup{privatecharbuffer[]=newchar[6];privateintnext=0;//Flagstokeeptrackof
ourbufferstatusprivatebooleanisFull=false;privatebooleanisEmpty
=true;publicsyschronizedchareat(){//Wecan\'teatifthereisn\'tanything
inthebufferwhile(isEmpty==true){try{wait();//we\'llexitthis
whenisEmptyturnsfalse}catch(InterruptedExceptione){}}//decrement
thecount,sincewe\'regoingtoeatoneletternext--;//Didweeatthe
lastletter?if(next==0){isEmpty=true;}//Weknowthebuffercan\'t
befull,becausewejustateisFull=false;notify();//returntheletter
tothethreadthatiseatingreturn(buffer[next]);}
//methodtoaddletterstothebufferpublicsynchronizedvoidadd(char
c){//Waitarounduntilthere\'sroomtoaddanotherletterwhile(isFull
==true){try{wait();//ThiswillexitwhenisFullturnsfalse}catch
(InterruptedExceptione){}}//addthelettertothenextavailablespot
buffer[next]=c;//Changethenextavailablespotnext++;//Arewefull;
if(next==6){isFull=true;}isEmpty=false;notify();}}soup類(lèi)包含兩個(gè)重要特征:數(shù)據(jù)成員buffer[]是私有的,功能成員add()和eat()是公有的。
數(shù)據(jù)私有避免了生產(chǎn)者和消費(fèi)者直接獲得數(shù)據(jù)。直接訪(fǎng)問(wèn)數(shù)據(jù)可能造成錯(cuò)誤。例如,如果消費(fèi)者企圖從空緩沖區(qū)里取出數(shù)據(jù),你將得到不必要的異常,否則,你只能鎖住進(jìn)程。同步訪(fǎng)問(wèn)方法避免了破壞一個(gè)共享對(duì)象。當(dāng)生產(chǎn)者向soup里加入一個(gè)字母時(shí),消費(fèi)者不能吃字符,諸如此類(lèi)。這種同步是維持共享對(duì)象完整性的重要方面。notify()函數(shù)將喚醒每一個(gè)等待線(xiàn)程。等待線(xiàn)程將繼續(xù)它的訪(fǎng)問(wèn)。
1.3.5聯(lián)系起來(lái)
現(xiàn)在我們有一個(gè)生產(chǎn)者,一個(gè)消費(fèi)者和一個(gè)共享對(duì)象,怎樣實(shí)現(xiàn)它們的交互呢?我們只需要一個(gè)簡(jiǎn)單的控制程序來(lái)啟動(dòng)所有的線(xiàn)程并確信每一個(gè)線(xiàn)程都是訪(fǎng)問(wèn)的同一個(gè)共享對(duì)象。下面是控制程序的代碼,SoupTest.java:
classSoupTest{publicstaticvoidmain(Stringargs[]){Soups=new
Soup();Producerp1=newProducer(s);Consumerc1=newConsumer(s);
p1.start();c1.start();}}
1.3.6監(jiān)視生產(chǎn)者
生產(chǎn)者/消費(fèi)者模型程序經(jīng)常用來(lái)實(shí)現(xiàn)遠(yuǎn)程監(jiān)視功能,它讓消費(fèi)者看到生產(chǎn)者同用戶(hù)的交互或同系統(tǒng)其它部分的交互。例如,在網(wǎng)絡(luò)中,一組生產(chǎn)者線(xiàn)程可以在很多工作站上運(yùn)行。生產(chǎn)者可以打印文檔,文檔打印后,一個(gè)標(biāo)志將保存下來(lái)。一個(gè)(或多個(gè)?copy;消費(fèi)者將保存標(biāo)志并在晚上報(bào)告白天打印活動(dòng)的情況。另外,還有例子在一個(gè)工作站是分出幾個(gè)獨(dú)立的窗口。一個(gè)窗口用作用戶(hù)輸入(生產(chǎn)者)另一個(gè)窗口作出對(duì)輸入的反應(yīng)(消費(fèi)者)。
1.4線(xiàn)程API列表
下面是一個(gè)常用的線(xiàn)程類(lèi)的方法函數(shù)列表:類(lèi)函數(shù):以下是Thread的靜態(tài)函數(shù),即可以直接從Thread類(lèi)調(diào)用。
currentThread返回正在運(yùn)行的Thread對(duì)象yield停止運(yùn)行當(dāng)前線(xiàn)程,讓系統(tǒng)運(yùn)行下一個(gè)線(xiàn)程sleep(intn)讓當(dāng)前線(xiàn)程睡眠n毫秒對(duì)象函數(shù):以下函數(shù)必須用Thread的實(shí)例對(duì)象來(lái)調(diào)用。
startstart函數(shù)告訴java運(yùn)行系統(tǒng)為本線(xiàn)程建立一個(gè)執(zhí)行環(huán)境,然后調(diào)用本線(xiàn)程的run()函數(shù)。run是運(yùn)行本線(xiàn)程的將要執(zhí)行的代碼,也是Runnable接口的唯一函數(shù)。當(dāng)一個(gè)線(xiàn)程初始化后,由start函數(shù)來(lái)調(diào)用它,一?copy;run函數(shù)返回,本線(xiàn)程也就終止了。stop讓某線(xiàn)程馬上終止,系統(tǒng)將刪除本線(xiàn)程的執(zhí)行環(huán)境suspend與stop函數(shù)不同,suspend將線(xiàn)程暫停執(zhí)行,但系統(tǒng)不破壞線(xiàn)程的執(zhí)行環(huán)境,你可以用resume來(lái)恢復(fù)本線(xiàn)程的執(zhí)行resume恢復(fù)被掛起的線(xiàn)程進(jìn)入運(yùn)行狀態(tài)setPriority(intp)給線(xiàn)程設(shè)置優(yōu)先級(jí)getPriority返回線(xiàn)程的優(yōu)先級(jí)setName(Stringname)給線(xiàn)程設(shè)置名稱(chēng)getName取線(xiàn)程的名稱(chēng)
【Java多線(xiàn)程知識(shí)點(diǎn)】相關(guān)文章:
java多線(xiàn)程08-31
java的多線(xiàn)程09-09
java語(yǔ)言的多線(xiàn)程08-29
Java多線(xiàn)程的開(kāi)發(fā)技巧10-16
Java多線(xiàn)程問(wèn)題總結(jié)10-24
高級(jí)Java多線(xiàn)程面試題及回答06-08