實驗2線程與同步解答_第1頁
實驗2線程與同步解答_第2頁
實驗2線程與同步解答_第3頁
實驗2線程與同步解答_第4頁
實驗2線程與同步解答_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實驗二 線程與同步一、實驗目的1 理解線程的基本概念2 掌握Java中線程類與Runnable接口的應用3 掌握控制線程基本方法4 掌握Java中線程的同步與互斥的實現二、實驗內容1 驗證課堂練習的結果,下面是課堂練習的內容:(1) 編寫一個程序,能夠根據用戶的輸入的數值生成相應數目的線程,每個線程運行1秒后結束。(2) 編寫一個程序,能夠生成n個線程,每個線程每隔1秒打印自己的序號,當用戶輸入m后第m個線程結束。(3) 編寫一個程序,能夠生成n個線程,每個線程打印自己的序號后結束,但要求最終的打印的結果為n,n1,1。2 將第三題改寫為能夠按照任意順序結束。3 編寫一個程序(由若干個類組成)

2、,該程序能夠生成3個線程,其中2個線程向一個隊列中寫入數據,每次寫入1個字節(jié),1個線程從隊列中讀出數據,一次2個字節(jié)。要求讀寫交替運行,并注意數據的同步,而且隊列要借助數組實現。三、實驗步驟1 運行Eclipse,在其中新建一個Java工程JavaNetwork;2 創(chuàng)建package lab.lab2,并在其中創(chuàng)建一個Java類FirstThread并運行查看結果,其代碼如下:package lab.lab2;import java.io.*;public class FirstThread extends Threadpublic static void main(String args)

3、 int n;try n=Integer.parseInt(new BufferedReader(new InputStreamReader(System.in).readLine();for (int i=0;i<n;i+)(new FirstThread().start(); catch (IOException e) e.printStackTrace();public void run()System.out.println("Thread started.");try Thread.sleep(1000); catch (InterruptedExcepti

4、on e) e.printStackTrace();System.out.println("Thread ended.");運行該程序后,程序會等待用戶的輸入,如果用戶輸入:3結果將會是:Thread started.Thread started.Thread started.Thread ended.Thread ended.Thread ended.即程序會根據用戶輸入的數值來生成相應數目的線程,每個線程運行1秒后結束。3 在package lab.lab2中創(chuàng)建一個Java類SecondThread并運行查看結果,其代碼如下:package lab.lab2;impo

5、rt java.io.*;public class SecondThread extends Threadprivate int id;private boolean flag=true;private static SecondThread t;private static int n=5;public SecondThread(int id)this.id=id;public void stopThread()flag=false;public boolean getThreadState()return flag;public static void main(String args)

6、int m;t=new SecondThreadn;for (int i=0;i<n;i+)(ti=new SecondThread(i).start();while(testThreads()try m=Integer.parseInt(new BufferedReader(new InputStreamReader(System.in).readLine();tm.stopThread(); catch (IOException e) e.printStackTrace();System.out.println("program ended.");public v

7、oid run()System.out.println("Thread "+id+" started.");while (flag)try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace();System.out.println("Thread "+id+" ended.");private static boolean testThreads()boolean flag=false;for (int i=0;i<n;i

8、+)flag|=ti.getThreadState();return flag;運行該程序后,屏幕將首先出現:Thread 0 started.Thread 1 started.Thread 2 started.Thread 3 started.Thread 4 started.然后等待用戶輸入,如果這時用戶依次輸入0、3、2、1、4,屏幕將依次出現0Thread 0 ended.3Thread 3 ended.2Thread 2 ended.1Thread 1 ended.4program ended.Thread 4 ended.即程序會根據用戶輸入的數值來結束相應序號的線程,所有線程結束

9、后程序結束。4 在package lab.lab2中創(chuàng)建一個Java類ThirdRunnable并運行查看結果,其代碼如下:package lab.lab2;public class ThirdRunnable implements Runnableprivate int id;private static int stopid=-1;static int n=10;public ThirdRunnable(int id)this.id=id;public static void main(String args) for (int i=1;i<=n;i+)new Thread(new

10、ThirdRunnable(i).start();stopid=n;public void run()System.out.println("Thread "+id+" started.");while (id!=stopid)Thread.yield();System.out.println("Thread "+id+" ended.");stopid-;運行該程序后,屏幕將出現:Thread 1 started.Thread 2 started.Thread 3 started.Thread 4 started

11、.Thread 5 started.Thread 6 started.Thread 7 started.Thread 8 started.Thread 9 started.Thread 10 started.Thread 10 ended.Thread 9 ended.Thread 8 ended.Thread 7 ended.Thread 6 ended.Thread 5 ended.Thread 4 ended.Thread 3 ended.Thread 2 ended.Thread 1 ended.即程序會根據按照正序啟動10個線程,然后逆序結束線程。5 將ThirdRunnable類改

12、寫,使其能夠按照任意順序結束;下面是就是改寫后的結果。package lab.lab2;public class FourthRunnable implements Runnable/線程按照下面熟組元素的順序依次結束。private static int t=4,5,9,3,1,0,2,6,8,7;private int id;private static int stopid=0;public FourthRunnable(int id)this.id=id;public static void main(String args) for (int i=0;i<t.length;i+

13、)(new Thread(new FourthRunnable(i).start();public void run()System.out.println("Thread "+id+" started.");try Thread.sleep(2000); catch (InterruptedException e) e.printStackTrace();while (id!=tstopid)Thread.yield();System.out.println("Thread "+id+" ended.");sto

14、pid+;6 編寫代碼實現實驗內容中的第3題。四、調試分析在調試線程程序的過程中,并干擾到其它應用程序的正常運行,后來經過仔細觀察,發(fā)現是因為在線程的循環(huán)體當中沒有調用sleep語句,從而導致線程不斷地搶占CPU,從而影響其它程序的正常運行。五、實驗結果按照指導書的步驟完成了第1題和第2題,同時編寫程序完成了第3題,達到了所要求的實驗結果。第3題的源代碼如下:/環(huán)形隊列package lab.lab2;public class DataQuque final int MAXLENGTH=10;byte data=new byteMAXLENGTH;int length;int startpos

15、;int endpos;public int read()int b;if (length<2)return -1;else if(startpos=MAXLENGTH-2)b=dataMAXLENGTH-2;b=b<<8;b|=dataMAXLENGTH-1;startpos=0;length-=2;return b;else if(startpos=MAXLENGTH-1)b=dataMAXLENGTH-1;b=b<<8;b|=data0;length-=2;startpos=1;return b;elseb=datastartpos;b=b<<8

16、;b|=datastartpos+1;length-=2;startpos+=2;return b;public boolean write(int b)if (length=MAXLENGTH)return false;else if(endpos=MAXLENGTH-1)dataMAXLENGTH-1=(byte)b;endpos=0;length+;return true;elsedataendpos+=(byte)b;length+;return true;/讀取線程package lab.lab2;public class DataReader extends Thread bool

17、ean flag = true;DataQuque dq;int id;public DataReader(DataQuque dq, int id) this.dq = dq;this.id = id;public void run() int b;try Thread.sleep(1000*id); catch (InterruptedException e) e.printStackTrace();while (flag) synchronized (dq) if (b = dq.read() = -1)try dq.wait(); catch (InterruptedException

18、 e1) e1.printStackTrace();else System.out.println("read:" + b+" dq:"+dq.length);System.out.flush();dq.notifyAll();public void stopThread() flag = false;/寫入線程package lab.lab2;public class DataWriter extends Threadboolean flag = true;DataQuque dq;int id;public DataWriter(DataQuque

19、dq, int id) this.dq = dq;this.id = id;public void run() try Thread.sleep(1000*id); catch (InterruptedException e) e.printStackTrace();while (flag) synchronized (dq) if (!dq.write(id)try dq.wait(); catch (InterruptedException e) e.printStackTrace();elsedq.notifyAll();System.out.println("write:&q

20、uot;+id+" dq:"+dq.length);System.out.flush();public void stopThread() flag = false;/控制類(程序入口)package lab.lab2;public class DataController public static void main(String args) DataQuque dq=new DataQuque();DataWriter dw1=new DataWriter(dq,1);DataWriter dw2=new DataWriter(dq,2);DataReader dr=

21、new DataReader(dq,3);dw1.start();dw2.start();dr.start();try Thread.sleep(5000); catch (InterruptedException e) e.printStackTrace();dw1.stopThread();dw2.stopThread();dr.stopThread();六、實驗總結通過本次實驗,熟悉了Java中線程的創(chuàng)建有二個方法,特別是runnable 接口的練習。需要在創(chuàng)建線程時候的參數是 runnable 類的對象。七、課后練習1 編寫一個多線程程序,該程序主要完成以下工作:(1)生成兩個發(fā)送線程

22、s1,s2和一個接收線程r;(2)接收線程r每接收到M個來自于s1的數據和N個s2的數據后將它們分別求平均值后輸出;(3)這樣的接收過程總共進行3次。/接收線程package thread.control;import java.util.*;public class DataReciever extends ThreadArrayList datalist=new ArrayList();final int MAX=10;/最多只能有10個發(fā)送線程int datanum=new intMAX; /每個發(fā)送者每次能夠發(fā)送的數據數int datalength=new intMAX;/每個發(fā)送者能

23、夠發(fā)送的數據總數int datacount=new intMAX; /每個發(fā)送者目前已紀發(fā)送的數據數int average=new intMAX;int senderId;int size;int total;volatile int count;public DataReciever()public int connect(int datasize,int maxlength)datanumsenderId=datasize;datalengthsenderId=maxlength;total+=maxlength;size+=datasize;int data=new intdatasiz

24、e;/該發(fā)送線程的數據存儲數組datalist.add(data);return senderId+;public void run()int printcount=0;int tempcount;while(true)tempcount=count;/count在運行中有可能會被接收線程改變,所以這里將它賦值給一個臨時變量,以防止因它在運行過程中被改變而造成程序產生錯誤。if (tempcount%size=0)&& (tempcount>0) if (printcount!=tempcount)printcount=tempcount;/注意位置printResult

25、();resetSenders();if (tempcount>=total) break;public boolean setData(int id,int data)/新增數據if (datacountid=datanumid)return false;addData(id,data);return true;private void addData(int id,int data)int temp=(int)datalist.get(id);tempdatacountid=data;datacountid+;count+;private void printResult()/打印結

26、果for (int i=0;i<senderId;i+)int data=(int )datalist.get(i);System.out.println("nn Data form sender "+i+" : ");for (int j=0;j<datanumi;j+)System.out.print(dataj+" ");averagei+=dataj;averagei/=datanumi;System.out.println("n Average : "+averagei);private vo

27、id resetSenders() /清空數據存儲數組,準備接收下一組數據。for (int i=0;i<senderId;i+)datacounti=0;/發(fā)送線程package thread.control;import java.util.Random;public class DataSender extends ThreadDataReciever dr;int id;int datasize; /求平均所需的數據數(M或N)int maxlength; /總共要發(fā)送的數據數(M*TIMES或N*TIMES)int count;public DataSender(DataRec

28、iever dr,int datasize,int maxlength) this.dr=dr;this.datasize=datasize;this.maxlength=maxlength;id=dr.connect(datasize,maxlength);/與接收線程連接,讓接收線程為本發(fā)送線程建立數據傳送通道(標識,數據數組,每次發(fā)送的數據長度,所有數據數)public void run() while (count < maxlength) /數據超過最大數則結束線程int data = 0xFF&generateData();/隨機產生一個數據while (!dr.se

29、tData(id, data) /發(fā)送數據Thread.yield();System.out.print(""+id+".<"+data+">.");count+;private int generateData() Random r=new java.util.Random();return r.nextInt();/控制類(產生兩個發(fā)送線程和一個接收線程。)package thread.control;public class DataMain public static void main(String args)

30、final int TIMES=4;final int M=3,N=5;DataSender s1,s2;DataReciever r=new DataReciever();s1=new DataSender(r,M,M*TIMES);s2=new DataSender(r,N,N*TIMES);r.start();s1.start();s2.start();2 編寫一個多線程程序,模擬多個售票點聯(lián)網出售火車票的場景,假設車票有10張,購票人有20人,售票點有3個,要求最終能夠輸出每張車票的票號、售出地點、乘客姓名。/乘客類package lab.lab2.ex2;public class P

31、erson public int personid;public String name;public Person(int personid)this.personid=personid;/火車票類package lab.lab2.ex2;public class Ticket public int ticketno;public String description;public Ticket(int ticketno)this.ticketno=ticketno;/售票點類package lab.lab2.ex2;import java.util.*;public class Posit

32、ion extends Threadint positionid;/售票點標識ArrayList<Person> personlist;/參加排隊的乘客列表ArrayList<Ticket> ticketlist;/所有的火車票列表static boolean soldoutflag=false;/標記票是否售完public Position(int positionid,ArrayList<Ticket> ticketlist)this.positionid=positionid;this.ticketlist=ticketlist;personlist=new ArrayList<Person>();public void addPerson(Person p)/增加一個人排隊personlist.add(p);public boolean sellTicket(Person p)/售票synchronized(ticketlist)if (soldoutflag) return false;Iterator it = ticketlist.iterator();Ticket t=null;if (it.hasNext()t

溫馨提示

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

評論

0/150

提交評論