北大計算機系java培訓(xùn)講義7線程_第1頁
北大計算機系java培訓(xùn)講義7線程_第2頁
北大計算機系java培訓(xùn)講義7線程_第3頁
北大計算機系java培訓(xùn)講義7線程_第4頁
北大計算機系java培訓(xùn)講義7線程_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第7章 多線程北京大學計算機系代亞非2第7章 多線程7.1 多線程基本概念7.2 創(chuàng)建線程的方式7.3 線程的掛起與喚醒7.4 多線程問題7.5 小結(jié)37.1 多線程基本概念文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段只有一個地方在執(zhí)行文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段同時有數(shù)個地方在執(zhí)行傳統(tǒng)的進程多線程的任務(wù)47.1 多線程基本概念多線程的優(yōu)勢:減輕編寫交互頻繁、涉及面多的程序的困難.程序的吞吐量會得到改善.由多個處理器的系統(tǒng),可以并發(fā)運行不同的線程.(否則,任何時刻只有一個線程在運行)57.1 多線程基本概念線程與進程的區(qū)別:多個進程的內(nèi)部數(shù)據(jù)和狀態(tài)都是完全獨立的,而多線程是共享

2、一塊內(nèi)存空間和一組系統(tǒng)資源,有可能互相影響.線程本身的數(shù)據(jù)通常只有寄存器數(shù)據(jù),以及一個程序執(zhí)行時使用的堆棧,所以線程的切換比進程切換的負擔要小。67.1 多線程基本概念對線程的綜合支持是Java技術(shù)的一個重要特色.它提供了thread類、監(jiān)視器和條件變量的技術(shù).雖然Macintosh,Windows NT,Windows 9等操作系統(tǒng)支持多線程,但若要用C或C+編寫多線程程序是十分困難的,因為它們對數(shù)據(jù)同步的支持不充分.77.2 創(chuàng)建線程的方式1. public class mythread extends Applet implements Runnable (小應(yīng)用或已經(jīng)是某個類的子類時)

3、2. 繼承類Thread public class mythread extends Thread3. 上述兩種方法中都可用類Thread產(chǎn)生線程的對象 Thread newthread;4. 創(chuàng)建并啟動線程 newthread=new Thread(this); newthread.start();87.2 創(chuàng)建線程的方式5. run方法是運行線程的主體,啟動線程時,由java直接調(diào)用 public void run() 6.停止線程,由小應(yīng)用程序的stop調(diào)用線程的stop newthread.stop() 7 sleep方法的作用,暫停線程的執(zhí)行,讓其它線程得到機會,sleep要丟出異常

4、,必須抓住.Trysleep(100)catch(InterruptedException e) 例:小應(yīng)用程序中不用Runnable接口仍然可以使用線程(不調(diào)用主類的方法和調(diào)用主類的方法) 9import java.applet.*;public class thread extends Applet mythread t1=new mythread(); public init() t1.start();class mythread extends Thread public void run() for (int i=0;i4;i+) System.out.println( “”+i);

5、 trysleep(400); catch(InteruptedException e) 7.2 創(chuàng)建線程的方式107.2 創(chuàng)建線程的方式public class mainclass extends Applet C t1=new C(this); public void init() t1.start(); public void paint(Graphics g) g.drawString(Hello,java,10,50);class C extends Threadmainclass a;C(mainclass b) a=b; public void run() while(true)

6、 a.repaint();trysleep(400); catch(InterruptedException e) 117.2 創(chuàng)建線程的方式8.其它常用的方法 isAlive :判斷線程目前是否正在執(zhí)行狀態(tài)中 if(newthread.isAlive() newthread.stop(); resume:要求被暫停得線程繼續(xù)執(zhí)行 suspend:暫停線程的執(zhí)行 join:等待線程執(zhí)行完畢 thatThread.join();被等待的那個線程不結(jié)束,當前線程就一直等待. yield:將執(zhí)行的權(quán)力交給其它線程,自己到隊列的最后等待.127.2 創(chuàng)建線程的方式9.線程的優(yōu)先權(quán)某一時刻只有一個線程在

7、執(zhí)行,調(diào)度策略為固定優(yōu)先級調(diào)度.newthread.setPriority(Thread.MIN_PRIORITY)級別有:MIN-PRIORITY NOM_PRIORITY MAX-PRIORITY10. 自私的線程:有很高的優(yōu)先權(quán)的線程,不主動睡眠或讓出處理器控制權(quán).137.2 創(chuàng)建線程的方式new Thread()New ThreadRunnablestart()Not Runnablestop()stop()Deadyield()stop() orrun()exit.suspend()sleep()wait()resume().11. 線程的狀態(tài)147.2 創(chuàng)建線程的方式當一個線程執(zhí)行

8、完所有語句后就自動終止,調(diào)用線程的stop()方法,也可以強制終止線程。如果希望線程正常終止,可采用標記來使線程中的run()方法退出。157.2 創(chuàng)建線程的方式public class Xyz implements Runnable private boolean timeToQuit=false; public void run() while (!timeToQuit) . /clean up before run() ends; public void stopRunning() timeToQuit=true; 167.2 創(chuàng)建線程的方式public class ControlThr

9、ead private Runnable r=new Xyz(); private Thread t=new Thread(r); public void startThread() t.start(); publi void stopThread() r.stopRunning();177.3 線程的掛起與喚醒暫停線程的執(zhí)行等待條件滿足再執(zhí)行.下面的例子顯示線程的掛起和喚醒小應(yīng)用程序第一次開始時,線程被啟動瀏覽器改變頁面時,小應(yīng)用程序的stop()方法被調(diào)用,線程被掛起.瀏覽器回到原來的頁面時,線程被喚醒.187.3 線程的掛起與喚醒public void start() if (mythr

10、ead=null) mythread=new Thread(); mythread.start(); else mythread.resume();public void run() while(true) trysleep(100); catch(InterruptedException e) public void stop()mythread.suspend();.197.4 多線程問題-執(zhí)行的順序多個線程運行時,調(diào)度策略為固定優(yōu)先級調(diào)度.級別相同時,由操作系統(tǒng)按時間片來分配下面給出的例子中,共運行三個線程,它們做同樣的事, 每次打印循環(huán)次數(shù)和自己的序列號,運行結(jié)果表明,它們并不是連續(xù)運

11、行的.在上例中如果給某個線程賦予較高的優(yōu)先權(quán),則發(fā)現(xiàn)這個進程壟斷控制權(quán) thread.setPriority(Thread.MAX_PRIORITY)threadmultithread.class-f1.batthreadPriority.class-f2.bat207.3 多線程問題/多個進程運行時執(zhí)行順序是交叉的class multithread extends Thread int threadNum; public static void main(String args) multithread array=new multithread3; for (int i=0;i3;i+)

12、arrayi=new multithread(i); for (int i=0;i3;i+) arrayi.start(); multithread(int SerialNum) super(); threadNum=SerialNum; public void run() for(int j=0;j5;j+)System.out.println(“ +MySerialNum); System.out.println(thread +threadNum+ bye.);217.4 多線程問題-如何寫多線程1.分別定義不同的線程類,在各自的run方法中定義線程的工作 class mythread1

13、 extends Thread public void run. class mythread2 extends Thread public void run. 2. 在主類中實例化各線程類,并啟動線程. public class demo extends Applet public void init() mythread t1=new mythread1(); mythread t2=new mythread2(); t1.start(); t2.start(); 227.4 多線程問題-如何寫多線程練習:將窗口分為上下兩個區(qū),分別運行兩個線程,一個在上面的區(qū)域中顯示由右向左游動的字符串,

14、另一個在下面的區(qū)域從左向右游動的字符串.方法一: 一個線程,在paint方法中使用兩個輸出字符串的語句public void paint(Graphics g) if y1200 y2=0 else y2=y2+10; g.drawString(“hello, Java!”,20,y1,); g.drawString(“hello, Java!”,40,y2,);237.4 多線程問題-如何寫多線程方法二:定義兩個類,運行各自的線程,各自有自己的paint()方法.注意: 兩個小應(yīng)用程序必須是panel類或者是canvas類,將小應(yīng)用的區(qū)域分成兩塊,否則不能運行paint語句.247.4 多線

15、程問題-線程間的通信1. 線程間的通信可以用管道流,.創(chuàng)建管道流:PipedInputStream pis=new PipedInputStream();PipedOutputStream pos=new PipedOutputStream(pis);或:PipedOutputStream pos=new PipedOutputStream();PipedInputStream pis=new PipedInputStream(pos);線程1PipedOutputStreamPipedInputStream輸出流outStream輸入流inStream線程2257.4 多線程問題-線程間的通

16、信管道流不能直 接讀寫PrintStream p = new PrintStream( pos );p.println(“hello”);DataInputStream d=new DataInputStream(pis);d.readLine();2. 通過一個中間類來傳遞信息.線程2線程1中間類mssm.write(s)s=m.read()write()read()printStream DataInputStream267.4 多線程問題-線程間的通信管道流可以連接兩個線程間的通信下面的例子里有兩個線程在運行,一個往外輸出信息,一個讀入信息.將一個寫線程的輸出通過管道流定義為讀線程的輸入

17、.outStream = new PipedOutputStream();inStream = new PipedInputStream(outStream);new Writer( outStream ).start();new Reader( inStream ).start(); 27(threadPipethread.class-f3.bat)7.4 多線程問題-線程間的通信主類Pipethread輔類Writer線程類輔類Reader線程類管道流將數(shù)據(jù)寫到輸出流從流中讀數(shù)據(jù)輸入流作為參數(shù)傳給WriterWriter( outStream )287.4 多線程問題-線程間的通信.pub

18、lic class Pipethread public static void main(String args) Pipethread thisPipe = new Pipethread(); thisPcess(); public void process() PipedInputStream inStream; PipedOutputStream outStream; PrintStream printOut; try outStream = new PipedOutputStream(); inStream = new PipedInputStream(outStream

19、); new Writer( outStream ).start(); new Reader( inStream ).start(); catch( IOException e ) 297.4 多線程問題-線程間的通信class Reader extends Thread private PipedInputStream inStream;/從中讀數(shù)據(jù) public Reader(PipedInputStream i) inStream = i; public void run() String line; DataInputStream d; boolean reading = true;

20、try d = new DataInputStream( inStream ); while( reading & d != null) tryline = d.readLine(); if( line != null ) System.out.println( ”Read: + line ); else reading = false; catch( IOException e) catch( IOException e ) System.exit(0); try Thread.sleep( 4000 ); catch( InterruptedException e )307.4 多線程問題

21、-線程間的通信.class Writer extends Thread private PipedOutputStream outStream;/將數(shù)據(jù)輸出 private String messages = Monday, Tuesday , Wednsday,Thursday,Friday :, Saturday:,Sunday :; public Writer(PipedOutputStream o) outStream = o; public void run() PrintStream p = new PrintStream( outStream ); for (int i = 0;

22、 i messages.length; i+) p.println(messages i ); p.flush(); System.out.println(WrIte: + messagesi ); p.close(); p = null; 317.3 多線程問題-資源協(xié)調(diào)1. 數(shù)據(jù)的完整性線程1線程2線程10資源取過來加1后送回去withdrwal()withdrwal()透支余額變量327.3 多線程問題-資源協(xié)調(diào)對共享對象的訪問必須同步,叫做條件變量.Java語言允許通過監(jiān)視器(有的參考書稱其為管程)使用條件變量實現(xiàn)線程同步.監(jiān)視器阻止兩個線程同時訪問同一個條件變量.它的如同鎖一樣作用在

23、數(shù)據(jù)上.線程1進入withdrawal方法時,獲得監(jiān)視器(加鎖);當線程1的方法執(zhí)行完畢返回時,釋放監(jiān)視器(開鎖),線程2的withdrawal方能進入.withdrawal()線程1監(jiān)視器線程2337.3 多線程問題-資源協(xié)調(diào)用synchronized來標識的區(qū)域或方法即為監(jiān)視器監(jiān)視的部分。一個類或一個對象由一個監(jiān)視器,如果一個程序內(nèi)有兩個方法使用synchronized標志,則他們在一個監(jiān)視器管理之下.一般情況下,只在方法的層次上使用關(guān)鍵區(qū)readwrite監(jiān)視器線程1線程2347.3 多線程問題-資源協(xié)調(diào)此處給出的例子演示兩個線程在同步限制下工作的情況.class Account sta

24、tics int balance=1000; /為什么用static? statics int expense=0; public synchronized void withdrawl(int amount) if (amountf4.bat377.3 多線程問題-資源協(xié)調(diào)writerreaderaaaabbbbbccccaaaaaaaaaaaaaaaaaaaaaaaabbbbbccccccccccccccccbbbbbcccc387.3 多線程問題-資源協(xié)調(diào)class WaitNotifyDemo public static void main(String args) MessageBo

25、ard m = new MessageBoard(); Reader readfrom_m = new Reader(m); Writer writeto_m=new Writer(m); readfrom_m.start(); writeto_m.start(); 397.3 多線程問題-資源協(xié)調(diào)class MessageBoard private String message; private boolean ready = false;(信號燈) public synchronized String read() while (ready = false) try wait(); cat

26、ch (InterruptedException e) ready = false; notify(); /起始狀態(tài)先寫后讀return message; public synchronized void write(String s) while (ready = true) try wait(); catch (InterruptedException e) message = s; ready = true; notify(); 407.3 多線程問題-資源協(xié)調(diào)class Reader extends Thread private MessageBoard mBoard; public

27、Reader(MessageBoard m) mBoard = m; public void run() String s = ;boolean reading = true;while( reading ) s = mBoard.read(); System.out.println(Reader read: + s); if( s.equals(logoff) ) reading = false; System.out.println(Finished: 10 seconds.);try sleep( 10000 ); catch (InterruptedException e) 417.3 多線程問題-資源協(xié)調(diào)class Writer extends Thread private MessageBoard mBoard; private String messages = Monday :-,“.”,Sunday :

溫馨提示

  • 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

提交評論