Java多線程機(jī)制課件_第1頁
Java多線程機(jī)制課件_第2頁
Java多線程機(jī)制課件_第3頁
Java多線程機(jī)制課件_第4頁
Java多線程機(jī)制課件_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

11.1Java中的線程11.1.1程序、進(jìn)程與線程(1)程序是一段靜態(tài)的代碼,它是應(yīng)用軟件執(zhí)行的藍(lán)本。(2)進(jìn)程是程序的一次動(dòng)態(tài)執(zhí)行過程。

它對應(yīng)了從代碼加載、執(zhí)行至執(zhí)行完畢的一個(gè)完整過程,這個(gè)過程也是進(jìn)程本身從產(chǎn)生、發(fā)展至消亡的過程。(3)線程是比進(jìn)程更小的執(zhí)行單位。一個(gè)進(jìn)程在其執(zhí)行過程中,可以產(chǎn)生多個(gè)線程。

每個(gè)Java程序都有一個(gè)缺省的主線程。Java應(yīng)用程序總是從主類的main方法開始執(zhí)行。當(dāng)JVM加載代碼,發(fā)現(xiàn)main方法之后,就會(huì)啟動(dòng)一個(gè)線程,這個(gè)線程稱作“主線程”,該線程負(fù)責(zé)執(zhí)行main方法。那么,在main方法的執(zhí)行中再創(chuàng)建的線程,就稱為程序中的其它線程。只有當(dāng)程序中所有線程都執(zhí)行完畢,JVM才會(huì)結(jié)束Java應(yīng)用程序。11.1.2線程的狀態(tài)與生命周期

Java中的線程都是Thread類或其子類的對象。線程的生命周期經(jīng)歷4種狀態(tài):新建運(yùn)行中斷死亡等待隊(duì)列1、新建當(dāng)一個(gè)Thread類或其子類的對象被聲明并創(chuàng)建時(shí),新生的線程對象處于新建狀態(tài)。2、運(yùn)行

線程調(diào)用start()方法進(jìn)入隊(duì)列等待運(yùn)行。一旦線程獲得CPU控制權(quán),線程就進(jìn)入運(yùn)行狀態(tài),開始執(zhí)行run()方法。

注意:在線程沒有結(jié)束run()方法之前,不要再次調(diào)用start()方法。3、中斷

有4種原因造成程序中斷:(1)CPU資源從當(dāng)前線程切換給其他線程。(2)線程執(zhí)行了sleep(intm)方法。(3)線程執(zhí)行了wait()方法。(4)線程執(zhí)行期間,執(zhí)行某個(gè)操作進(jìn)入阻塞狀態(tài)。

一旦線程中斷,則程序在當(dāng)前運(yùn)行處停止,讓出CPU,中斷原因消失后,程序進(jìn)入隊(duì)列排隊(duì)直到再次獲得CPU的控制權(quán)時(shí)才從中斷處重新運(yùn)行。4、死亡當(dāng)線程對象釋放實(shí)體時(shí),線程進(jìn)入死亡狀態(tài)。有2種原因讓線程死亡:(1)run()方法正常執(zhí)行完畢(2)run()方法被提前強(qiáng)制結(jié)束例11.1publicclassExample11_1{publicstaticvoidmain(Stringargs[]){SpeakHellospeakHello;SpeakNinhaospeakNinhao;speakHello=newSpeakHello();speakNinhao=newSpeakNinhao();speakHello.start();speakNinhao.start();for(inti=1;i<=12;i++){System.out.print("我是主線程");}}}classSpeakHelloextendsThread{publicvoidrun(){for(inti=1;i<=12;i++){System.out.print("hello");}}}classSpeakNinhaoextendsThread{publicvoidrun(){for(inti=1;i<=12;i++){System.out.print("您好");}}}11.1.3線程調(diào)度與優(yōu)先級JVM中的線程調(diào)度器把線程優(yōu)先級分為10個(gè)級別,每個(gè)Java線程的優(yōu)先級都在常數(shù)1-10之間。線程的優(yōu)先級可以通過setPriority(intgrade)方法調(diào)整。當(dāng)grade不在1-10的范圍內(nèi),則拋出異常IllegalAgumenException。getPriority()返回線程的優(yōu)先級。Java調(diào)度器的任務(wù)是使高優(yōu)先級的線程能始終運(yùn)行。11.2Thread的子類創(chuàng)建線程

線程是Thread類或其子類創(chuàng)建的對象。

編寫Thread類的子類時(shí),需要重寫父類的run方法,其目的是規(guī)定線程的具體操作,否則線程就什么也不做,因?yàn)楦割惖膔un方法中沒有任何操作語句。例11.2publicclassExample11_2{publicstaticvoidmain(Stringargs[]){PeoplepersonOne,personTwo;StringBufferstr=newStringBuffer();personOne=newPeople("張三",str);personTwo=newPeople("李四",str);personOne.start();personTwo.start();}}classPeopleextendsThread{StringBufferstr;People(Strings,StringBufferstr){setName(s);this.str=str;}publicvoidrun(){for(inti=1;i<=3;i++){str.append(getName()+",");System.out.println("我是"+getName()+",字符串為:"+str);try{sleep(200);}catch(InterruptedExceptione){}}}}11.3使用Runable接口

創(chuàng)建線程的另一個(gè)途徑就是用Thread類直接創(chuàng)建線程對象:

Thread對象名=newThread(Runnabletarget);參數(shù)target被稱作所創(chuàng)線程的目標(biāo)對象目標(biāo)對象是一個(gè)實(shí)現(xiàn)Runnable接口的類的對象。可以向不同的線程對象傳遞同一個(gè)目標(biāo)對象,此時(shí)這些線程對象將共享目標(biāo)對象的成員變量。例11.3publicclassExample11_3{publicstaticvoidmain(Stringargs[]){Bankbank=newBank();bank.setMoney(300);ThreadthreadOne,threadTwo;threadOne=newThread(bank);threadOne.setName("One");threadTwo=newThread(bank);threadTwo.setName("Two");threadOne.start();threadTwo.start();}}classBankimplementsRunnable{privateintnumber=0;publicvoidsetMoney(intm){number=m;}publicvoidrun(){while(true){Stringname=Thread.currentThread().getName();if(name.equals("One")){if(number<=160){System.out.println(name+"進(jìn)入死亡狀態(tài)");return;}number=number+10;System.out.println("我是"+name+"現(xiàn)在number="+number);}if(Thread.currentThread().getName().equals("Two")){if(number<=0){System.out.println(name+"進(jìn)入死亡狀態(tài)");return;}number=number-100;System.out.println("我是"+name+"現(xiàn)在number="+number);}try{Thread.sleep(800);}catch(InterruptedExceptione){}}}}classExample11_4{publicstaticvoidmain(Stringargs[]){ThreadthreadA,threadB,threadC,threadD;TargetObjecta1=newTargetObject(),a2=newTargetObject();threadA=newThread(a1);threadB=newThread(a1);a1.setNumber(10);threadA.setName("add");threadB.setName("add");threadC=newThread(a2);threadD=newThread(a2);a2.setNumber(-10);threadC.setName("sub");threadD.setName("sub");threadA.start();threadB.start();threadC.start();threadD.start();}}例11.4

classTargetObjectimplementsRunnable{privateintnumber=0;publicvoidsetNumber(intn){number=n;}publicvoidrun(){while(true){if(Thread.currentThread().getName().equals("add")){number++;System.out.println("現(xiàn)在number等于"+number);}if(Thread.currentThread().getName().equals("sub")){number--;System.out.println("現(xiàn)在number等于"+number);}try{Thread.sleep(1000);}catch(InterruptedExceptione){}}}}11.3.2關(guān)于run()方法的局部變量

實(shí)現(xiàn)Runnable

接口的類,其成員變量被由同一個(gè)目標(biāo)對象創(chuàng)建的線程共享,但當(dāng)每個(gè)線程獲得CPU控制權(quán)時(shí),都會(huì)重新調(diào)用run()方法,所以run()方法中的局部變量各自獨(dú)享,互不干擾。

publicclassExample11_5{publicstaticvoidmain(Stringargs[]){Movemove=newMove();Threadzhangsan,lisi;zhangsan=newThread(move);zhangsan.setName("張三");lisi=newThread(move);lisi.setName("李四");zhangsan.start();lisi.start();}}classMoveimplementsRunnable{publicvoidrun(){Stringname=Thread.currentThread().getName();//局部變量nameStringBufferstr=newStringBuffer();//局部變量strfor(inti=1;i<=3;i++)//局部變量i{if(name.equals("張三")){str.append(name);System.out.println(name+"線程的局部變量i="+i+",str="+str);}elseif(name.equals("李四")){str.append(name);System.out.println(name+"線程的局部變量i="+i+",str="+str);}try{Thread.sleep(800);}catch(InterruptedExceptione){}}}}

線程通過調(diào)用start()方法將啟動(dòng)線程,使之從新建狀態(tài)進(jìn)入就緒隊(duì)列(等待隊(duì)列),一旦輪到它來享用CPU資源時(shí),就可以脫離創(chuàng)建它的線程,開始自己的生命周期。例子11.6publicclassExample11_6{publicstaticvoidmain(Stringargs[]){ComputerSumcomputer=newComputerSum();ThreadthreadOne;threadOne=newThread(computer);threadOne.setName("張三");threadOne.start();}}11.3.3在線程中啟動(dòng)其他線程classComputerSumimplementsRunnable{inti=1,sum=0;publicvoidrun(){Threadthread=Thread.currentThread();System.out.println(thread.getName()+"開始計(jì)算");while(i<=100){sum=sum+i;System.out.print(""+sum);if(i==50){System.out.println(thread.getName()+"完成任務(wù)了!i="+i);ThreadthreadTwo=newThread(this);threadTwo.setName("李四");threadTwo.start();i++;return;}i++;try{Thread.sleep(300);}catch(InterruptedExceptione){}}}}11.4線程的常用方法1.start()

線程調(diào)用該方法將啟動(dòng)線程,使之從新建狀態(tài)進(jìn)入就緒隊(duì)列排隊(duì),一旦輪到它來享用CPU資源時(shí),就可以脫離創(chuàng)建它的線程獨(dú)立開始自己的生命周期了。2.run()

Thread類的run()方法與Runnable接口中的run()方法的功能和作用相同,都用來定義線程對象被調(diào)度之后所執(zhí)行的操作,都是系統(tǒng)自動(dòng)調(diào)用而用戶程序不得引用的方法。系統(tǒng)的Thread類中,run()方法沒有具體內(nèi)容,所以用戶程序需要?jiǎng)?chuàng)建自己的Thread類的子類,并重寫run()方法來覆蓋原來的run()方法。當(dāng)run方法執(zhí)行完畢,線程就變成死亡狀態(tài)。3.sleep(intmillsecond)

現(xiàn)程占有CPU期間,執(zhí)行sleep方法來使自己放棄CPU資源,休眠一段時(shí)間。休眠時(shí)間的長短由sleep方法的參數(shù)決定,millsecond是毫秒為單位的休眠時(shí)間。如果線程在休眠時(shí)被打斷,JVM就拋出InterruptedException異常。因此,必須在try~catch語句塊中調(diào)用sleep方法。4.isAlive()

線程處于“新建”狀態(tài)時(shí),線程調(diào)用isAlive()方法返回false。當(dāng)一個(gè)線程調(diào)用start()方法,并占有CUP資源后,該線程的run方法就開始運(yùn)行,在線程的run方法結(jié)束之前,即沒有進(jìn)入死亡狀態(tài)之前,線程調(diào)用isAlive()方法返回true。當(dāng)線程進(jìn)入“死亡”狀態(tài)后(實(shí)體內(nèi)存被釋放),線程仍可以調(diào)用方法isAlive(),這時(shí)返回的值是false。一個(gè)已經(jīng)運(yùn)行的線程在沒有進(jìn)入死亡狀態(tài)時(shí),不要再給線程分配實(shí)體,由于線程只能引用最后分配的實(shí)體,先前的實(shí)體就會(huì)成為“垃圾”,并且不會(huì)被垃圾收集機(jī)收集掉。例子11.7importjava.util.Date;publicclassExample11_7{publicstaticvoidmain(Stringargs[]){Aa=newA();Threadthread=newThread(a);thread.start();}}classAimplementsRunnable{inttime=0;publicvoidrun(){while(true){System.out.println(newDate());time++;try{Thread.sleep(1000);}catch(InterruptedExceptione){}if(time==3){Threadthread=Thread.currentThread();thread=newThread(this);thread.start();}}}}5.currentThread()currentThread()方法是Thread類中的類方法,可以用類名調(diào)用,該方法返回當(dāng)前正在使用CPU資源的線程。

6.interrupt()intertupt方法經(jīng)常用來“吵醒”休眠的線程。當(dāng)一些線程調(diào)用sleep方法處于休眠狀態(tài)時(shí),一個(gè)占有CPU資源的線程可以讓休眠的線程調(diào)用interrupt方法“吵醒”自己。

注意:“吵醒”線程會(huì)拋出InterruptedException異常。例11.8publicclassExample11_8{publicstaticvoidmain(Stringargs[]){Aa=newA();a.student.start();a.teacher.start();}}classAimplementsRunnable{Threadstudent,teacher;A(){teacher=newThread(this);student=newThread(this);teacher.setName("王教授");student.setName("張三");}publicvoidrun(){if(Thread.currentThread()==student){try{System.out.println(student.getName()+"正在睡覺,不聽課");例11.8Thread.sleep(1000*60*60);}catch(InterruptedExceptione){System.out.println(student.getName()+"被老師叫醒了");}System.out.println(student.getName()+"開始聽課");}elseif(Thread.currentThread()==teacher){for(inti=1;i<=3;i++){System.out.println("上課!");try{Thread.sleep(500);}catch(InterruptedExceptione){}}errupt();//吵醒student}}}11.6線程同步1、線程同步線程同步是指若干個(gè)線程都需要使用一個(gè)synchronized修飾的方法。2、同步機(jī)制當(dāng)一個(gè)線程A使用一個(gè)synchronized修飾的方法時(shí),其他線程想使用這個(gè)方法時(shí)就必須等待,直到線程A使用完該方法(除非線程A使用wait主動(dòng)讓出CUP資源)。例11.11importjava.awt.*;importjava.awt.event.*;publicclassExample11_11{publicstaticvoidmain(Stringargs[]){newFrameMoney();}}classFrameMoneyextendsFrameimplementsRunnable,ActionListener{intmoney=100;TextAreatext1,text2;Thread會(huì)計(jì),出納;intweekDay;ButtonstartShowing=newButton("開始演示");FrameMoney(){會(huì)計(jì)=newThread(this);

出納=newThread(this);text1=newTextArea(10,12);text2=newTextArea(10,12);setLayout(newFlowLayout());add(startShowing);add(text1);add(text2);setVisible(true);setSize(520,300);validate();addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});startShowing.addActionListener(this);}publicvoidactionPerformed(ActionEvente){if(!(出納.isAlive())&&!(會(huì)計(jì).isAlive())){會(huì)計(jì)=newThread(this);

出納=newThread(this);text1.setText(null);text2.setText(null);money=100;}

try{會(huì)計(jì).start();

出納.start();}catch(Exceptionexp){}}publicsynchronizedvoid存取(intnumber)//存取方法

{if(Thread.currentThread()==會(huì)計(jì)){for(inti=1;i<=3;i++)//會(huì)計(jì)使用存取方法存入90元,存入30元,稍歇一下

{money=money+number;text1.append("帳上有"+money+"萬\n");try{Thread.sleep(1000);//這時(shí)出納仍不能使用存取方法

}//因?yàn)闀?huì)計(jì)還沒使用完存取方法

catch(InterruptedExceptione){}

}}elseif(Thread.currentThread()==出納){for(inti=1;i<=2;i++)//出納使用存取方法取出30元,取出15元,稍歇一下

{money=money-number/2;text2.append("帳上有"+money+"萬\n");try{Thread.sleep(1000);//這時(shí)會(huì)計(jì)仍不能使用存取方法}//因?yàn)槌黾{還沒使用完存取方法

catch(InterruptedExceptione){}}}}publicvoidrun(){StringweekDay[]={"星期一","星期二","星期三"};if(Thread.currentThread()==會(huì)計(jì)){for(Stringday:weekDay)//從星期一到星期三會(huì)計(jì)要使用帳本

{text1.append("今天是"+day+"\n");

存取(30);}}elseif(Thread.currentThread()==出納){for(Stringday:weekDay)//從星期一到星期三出納要使用帳本

{text2.append("今天是"+day+"\n");

存取(30);}}}}

11.7在同步方法中使用wait()、notify()和notifyAll()方法一個(gè)線程在使用的同步方法中時(shí),可能根據(jù)問題的需要,必須使用wait()方法使本線程等待,暫時(shí)讓出CPU的使用權(quán),并允許其它線程使用這個(gè)同步方法。其它線程如果在使用這個(gè)同步方法時(shí)如果不需要等待,那么它用完這個(gè)同步方法的同時(shí),應(yīng)當(dāng)執(zhí)行notifyAll()方法通知所有的由于使用這個(gè)同步方法而處于等待的線程結(jié)束等待。例11.12importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;publicclassExample11_12{publicstaticvoidmain(Stringargs[]){newMyFrame();}}classMyFrameextendsJFrameimplementsRunnable,ActionListener{售票員王小姐;Thread張平,李明;staticJTextAreatext;JButtonstartBuy=newJButton("開始買票");MyFrame(){王小姐=new售票員();

張平=newThread(this);

李明=newThread(this);text=newJTextArea(10,30);startBuy.addActionListener(this);add(text,BorderLayout.CENTER);add(startBuy,BorderLayout.NORTH);setVisible(true);setSize(360,300);validate();setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}publicvoidactionPerformed(ActionEvente){try{張平.start();

李明.start();}catch(Exceptionexp){}}publicvoidrun(){if(Thread.currentThread()==張平){王小姐.售票規(guī)則(20);}elseif(Thread.currentThread()==李明){王小姐.售票規(guī)則(5);}}}class售票員{int

五元錢的個(gè)數(shù)=2,十元錢的個(gè)數(shù)=0,二十元錢的個(gè)數(shù)=0;Strings=null;publicsynchronizedvoid售票規(guī)則(intmoney){if(money==5)//如果使用該方法的線程傳遞的參數(shù)是5,就不用等待

{五元錢的個(gè)數(shù)=五元錢的個(gè)數(shù)+1;s="給您入場卷您的錢正好";MyFrame.text.append("\n"+s);}elseif(money==20){while(五元錢的個(gè)數(shù)<3){try{wait();//如果使用該方法的線程傳遞的參數(shù)是20須等待

}catch(InterruptedExceptione){}}

五元錢的個(gè)數(shù)=五元錢的個(gè)數(shù)-3;

二十元錢的個(gè)數(shù)=二十元錢的個(gè)數(shù)+1;s="給您入場卷"+"您給我20,找您15元";MyFrame.text.append("\n"+s);}notifyAll();}}例11.13publicclassExample11_13{publicstaticvoidmain(Stringargs[]){Numbernumber=newNumber();number.giveNumberThread.start();number.guessNumberThread.start();}}classNumberimplementsRunnable{finalintSMALLER=-1,LARGER=1,SUCCESS=8;intrealNumber,guessNumber,min=0,max=100,message=SMALLER;booleanpleaseGuess=false,isGiveNumber=false;ThreadgiveNumberThread,guessNumberThread;Number(){giveNumberThread=newThread(this);guessNumberThread=newThread(this);}publicvoidrun(){for(intcount=1;true;count++){setMessage(count);if(message==SUCCESS)return;}}publicsynchronizedvoidsetMessage(intcount){if(Thread.currentThread()==giveNumberThread&&isGiveNumber==false){realNumber=(int)(Math.random()*100);System.out.println("隨機(jī)給你一個(gè)0至99之間的數(shù),猜猜是多少?");isGiveNumber=true;pleaseGuess=true;}if(Thread.currentThread()==giveNumberThread){while(pleaseGuess==true)try{wait();//讓出CPU使用權(quán),讓另一個(gè)線程開始猜數(shù)

}catch(InterruptedExceptione){}if(realNumber>guessNumber)//結(jié)束等待后,根據(jù)另一個(gè)線程的猜測給出提示

{message=SMALLER;System.out.println("你猜小了");}elseif(realNumber<guessNumber){message=LARGER;System.out.println("你猜大了");}else{message=SUCCESS;System.out.println("恭喜,你猜對了");}pleaseGuess=true;}if(Thread.currentThread()==guessNumberThread&&isGiveNumber==true){while(pleaseGuess==false)try{wait();//讓出CPU使用權(quán),讓另一個(gè)線程給出提示

}catch(InterruptedExceptione){}if(message==SMALLER){min=guessNumber;guessNumber=(min+max)/2;System.out.println("我第"+count+"次猜這個(gè)數(shù)是:"+guessNumber);}elseif(message==LARGER){max=guessNumber;guessNumber=(min+max)/2;System.out.println("我第"+count+"次猜這個(gè)數(shù)是:"+guessNumber);}pleaseGuess=false;}notifyAll();}}11.8掛起、恢復(fù)和終止線程1、掛起有時(shí)候兩個(gè)線程并不是同步的,即不涉及都需要調(diào)用一個(gè)同步方法,但線程也可能需要暫時(shí)的掛起。所謂掛起一個(gè)線程就是讓線程暫時(shí)讓出CPU的使用權(quán)限,暫時(shí)停止執(zhí)行,但停止執(zhí)行的持續(xù)時(shí)間不確定,因此不能使用sleep方法暫停線程。掛起一個(gè)線程需使用wait方法,即讓準(zhǔn)備掛起的線程調(diào)用wait方法,主動(dòng)讓出CPU的使用權(quán)限。2、恢復(fù)為了恢復(fù)該線程,其它線程在占有CUP資源期間,讓掛起的線程的目標(biāo)對象執(zhí)行notifyAll()方法,使得掛起的線程繼續(xù)執(zhí)行;如果線程沒有目標(biāo)對象,為了恢復(fù)該線程,其它線程在占有CUP資源期間,讓掛起的線程調(diào)用notifyAll()方法,使掛起的線程繼續(xù)執(zhí)行。例11.14classAimplementsRunnable{inti=0;Stringname;publicvoidrun(){while(true){i++;System.out.println(name+"i="+i);if(i==5){try{掛起線程();}catch(Exceptione){}}try{Thread.sleep(1000);}catch(Exceptione){}}}publicsynchronizedvoid掛起線程()throwsInterruptedException{wait();}publicsynchronizedvoid恢復(fù)線程(){notifyAll();}}publicclassExample11_14{publicstaticvoidmain(Stringargs[]){intm=0;Atarget=newA();//線程的目標(biāo)對象

="張三";Threadthread=newThread(target);thread.setName();thread.start();while(true){m++;System.out.println("我是主線程m="+m);if(m==20){System.out.println("讓"+thread.getName()+"繼續(xù)工作");try{target.恢復(fù)線程();//主線程占有CPU資源期間

}//讓thread的目標(biāo)對象調(diào)用notifyAll()catch(Exceptione){}break;}try{Thread.sleep(1000);}catch(Exceptione){}}}}

classMyThreadextendsThread{inti=0;publicvoidrun(){while(true){i++;System.out.println("我的名字是"+getName()+"i="+i);if(i==10){try{掛起線程();}catch(Exceptione){}}try{Thread.sleep(1000);}catch(Exceptione){}}}publicsynchronizedvoid掛起線程()throwsInterruptedException{wait();}publicsynchronizedvoid恢復(fù)線程(){notifyAll();}}classYourThreadextendsThread{intm=0;MyThreadotherThread;YourThread(MyThreada){otherThread=a;}publicvoidrun(){while(true){m++;System.out.println("我的名字是"+getName()+"m="+m);if(m==20){System.out.println("恢復(fù)線程:"+otherThread.getName());System.out.println(getName()+"停止工作");try{otherThread.恢復(fù)線程();}catch(Exceptione){}return;}try{Thread.sleep(1000);}catch(Exceptione){}}}}publicclassExample11_15{publicstaticvoidmain(Stringargs[]){MyThreadthread1=newMyThread();thread1.setName("張三");thread1.start();YourThreadthread2=newYourThread(thread1);thread2.setName("李四");thread2.start();}}例11.16importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;publicclassExample11_16{publicstaticvoidmain(Stringargs[]){Winwin=newWin();}}classWinextendsJFrameimplementsRunnable,ActionListener{ThreadmoveOrStop;JButton

開始,掛起,恢復(fù),終止;JLabelmoveLabel;booleanmove=false,die=false;Win(){moveOrStop=newThread(this);

開始=newJButton("線程開始");

掛起=newJButton("線程掛起");

恢復(fù)=newJButton("線程恢復(fù)");

終止=newJButton("線程終止");

開始.addActionListener(this);

掛起.addActionListener(this);

恢復(fù).addActionListener(this);

終止.addActionListener(this);moveLabel=newJLabel("線程負(fù)責(zé)運(yùn)動(dòng)我");moveLabel.setBackground(Color.cyan);setLayout(newFlowLayout());add(開始);add(掛起);add(恢復(fù));add(終止);add(moveLabel);setSize(200,300);validate();setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}publicvoidactionPerformed(ActionEvente){if(e.getSource()==開始){try{move=true;moveOrStop.start();}catch(Exceptionevent){}}elseif(e.getSource()==掛起){m

溫馨提示

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

評論

0/150

提交評論