




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、實驗二 線程與同步一、實驗?zāi)康? 理解線程的基本概念2 掌握J(rèn)ava中線程類與Runnable接口的應(yīng)用3 掌握控制線程基本方法4 掌握J(rèn)ava中線程的同步與互斥的實現(xiàn)二、實驗內(nèi)容1 驗證課堂練習(xí)的結(jié)果,下面是課堂練習(xí)的內(nèi)容:(1) 編寫一個程序,能夠根據(jù)用戶的輸入的數(shù)值生成相應(yīng)數(shù)目的線程,每個線程運行1秒后結(jié)束。(2) 編寫一個程序,能夠生成n個線程,每個線程每隔1秒打印自己的序號,當(dāng)用戶輸入m后第m個線程結(jié)束。(3) 編寫一個程序,能夠生成n個線程,每個線程打印自己的序號后結(jié)束,但要求最終的打印的結(jié)果為n,n1,1。2 將第三題改寫為能夠按照任意順序結(jié)束。3 編寫一個程序(由若干個類組成)
2、,該程序能夠生成3個線程,其中2個線程向一個隊列中寫入數(shù)據(jù),每次寫入1個字節(jié),1個線程從隊列中讀出數(shù)據(jù),一次2個字節(jié)。要求讀寫交替運行,并注意數(shù)據(jù)的同步,而且隊列要借助數(shù)組實現(xiàn)。三、實驗步驟1 運行Eclipse,在其中新建一個Java工程JavaNetwork;2 創(chuàng)建package lab.lab2,并在其中創(chuàng)建一個Java類FirstThread并運行查看結(jié)果,其代碼如下: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結(jié)果將會是:Thread started.Thread started.Thread started.Thread ended.Thread ended.Thread ended.即程序會根據(jù)用戶輸入的數(shù)值來生成相應(yīng)數(shù)目的線程,每個線程運行1秒后結(jié)束。3 在package lab.lab2中創(chuàng)建一個Java類SecondThread并運行查看結(jié)果,其代碼如下: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;運行該程序后,屏幕將首先出現(xiàn):Thread 0 started.Thread 1 started.Thread 2 started.Thread 3 started.Thread 4 started.然后等待用戶輸入,如果這時用戶依次輸入0、3、2、1、4,屏幕將依次出現(xiàn)0Thread 0 ended.3Thread 3 ended.2Thread 2 ended.1Thread 1 ended.4program ended.Thread 4 ended.即程序會根據(jù)用戶輸入的數(shù)值來結(jié)束相應(yīng)序號的線程,所有線程結(jié)束
9、后程序結(jié)束。4 在package lab.lab2中創(chuàng)建一個Java類ThirdRunnable并運行查看結(jié)果,其代碼如下: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-;運行該程序后,屏幕將出現(xiàn):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.即程序會根據(jù)按照正序啟動10個線程,然后逆序結(jié)束線程。5 將ThirdRunnable類改
12、寫,使其能夠按照任意順序結(jié)束;下面是就是改寫后的結(jié)果。package lab.lab2;public class FourthRunnable implements Runnable/線程按照下面熟組元素的順序依次結(jié)束。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 編寫代碼實現(xiàn)實驗內(nèi)容中的第3題。四、調(diào)試分析在調(diào)試線程程序的過程中,并干擾到其它應(yīng)用程序的正常運行,后來經(jīng)過仔細觀察,發(fā)現(xiàn)是因為在線程的循環(huán)體當(dāng)中沒有調(diào)用sleep語句,從而導(dǎo)致線程不斷地搶占CPU,從而影響其它程序的正常運行。五、實驗結(jié)果按照指導(dǎo)書的步驟完成了第1題和第2題,同時編寫程序完成了第3題,達到了所要求的實驗結(jié)果。第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();六、實驗總結(jié)通過本次實驗,熟悉了Java中線程的創(chuàng)建有二個方法,特別是runnable 接口的練習(xí)。需要在創(chuàng)建線程時候的參數(shù)是 runnable 類的對象。七、課后練習(xí)1 編寫一個多線程程序,該程序主要完成以下工作:(1)生成兩個發(fā)送線程
22、s1,s2和一個接收線程r;(2)接收線程r每接收到M個來自于s1的數(shù)據(jù)和N個s2的數(shù)據(jù)后將它們分別求平均值后輸出;(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ā)送的數(shù)據(jù)數(shù)int datalength=new intMAX;/每個發(fā)送者能
23、夠發(fā)送的數(shù)據(jù)總數(shù)int datacount=new intMAX; /每個發(fā)送者目前已紀(jì)發(fā)送的數(shù)據(jù)數(shù)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ā)送線程的數(shù)據(jù)存儲數(shù)組datalist.add(data);return senderId+;public void run()int printcount=0;int tempcount;while(true)tempcount=count;/count在運行中有可能會被接收線程改變,所以這里將它賦值給一個臨時變量,以防止因它在運行過程中被改變而造成程序產(chǎn)生錯誤。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)/新增數(shù)據(jù)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()/打印結(jié)
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() /清空數(shù)據(jù)存儲數(shù)組,準(zhǔn)備接收下一組數(shù)據(jù)。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; /求平均所需的數(shù)據(jù)數(shù)(M或N)int maxlength; /總共要發(fā)送的數(shù)據(jù)數(shù)(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ā)送線程建立數(shù)據(jù)傳送通道(標(biāo)識,數(shù)據(jù)數(shù)組,每次發(fā)送的數(shù)據(jù)長度,所有數(shù)據(jù)數(shù))public void run() while (count < maxlength) /數(shù)據(jù)超過最大數(shù)則結(jié)束線程int data = 0xFF&generateData();/隨機產(chǎn)生一個數(shù)據(jù)while (!dr.se
29、tData(id, data) /發(fā)送數(shù)據(jù)Thread.yield();System.out.print(""+id+".<"+data+">.");count+;private int generateData() Random r=new java.util.Random();return r.nextInt();/控制類(產(chǎn)生兩個發(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)網(wǎng)出售火車票的場景,假設(shè)車票有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;/售票點標(biāo)識ArrayList<Person> personlist;/參加排隊的乘客列表ArrayList<Ticket> ticketlist;/所有的火車票列表static boolean soldoutflag=false;/標(biāo)記票是否售完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)系上傳者。文件的所有權(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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 華為管理課件
- 河北96年中考數(shù)學(xué)試卷
- 淮海小升初數(shù)學(xué)試卷
- 健康管理師課件口碑
- 2025屆黑龍江省慶安縣第三中學(xué)物理高二下期末質(zhì)量跟蹤監(jiān)視試題含解析
- 2025年中國植物蛋白飲料行業(yè)市場調(diào)查研究及投資前景展望報告
- 交評報告匯報范本1看丹橋工業(yè)區(qū)項目交通影響評價
- 易拉蓋產(chǎn)品項目投資可行性研究分析報告(2024-2030版)
- 2025年中國停車場建設(shè)行業(yè)發(fā)展趨勢及投資前景預(yù)測報告
- 2025年廣州地鐵建設(shè)市場調(diào)研報告
- GB 11930-1989操作開放型放射性物質(zhì)的輻射防護規(guī)定
- 起重作業(yè)吊索具使用安全培訓(xùn)課件
- 中小學(xué)班主任工作手冊(修訂)
- 育嬰員中級近年考試真題匯總(含答案)
- 順德區(qū)國家工作人員因私出國(境)審批表
- 2022泉州實驗中學(xué)初一新生入學(xué)考試語文卷
- 高原切花玫瑰編制說明(農(nóng)標(biāo)委報批)
- 酒店住宿水單模板
- 安徽省安裝工程消耗量定額(共165頁)
- 《課程標(biāo)準(zhǔn)》編制說明
- 土方回填施工組織設(shè)計方案
評論
0/150
提交評論