实验2线程与同步解答_第1页
实验2线程与同步解答_第2页
实验2线程与同步解答_第3页
实验2线程与同步解答_第4页
实验2线程与同步解答_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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个字节,1个线程从队列中读出数据,一次2个字节。要求读写交替运行,并注意数据的同步,而且队列要借助数组实现。三、实验步骤1 运行Eclipse,在其中新建一个Java工程JavaNetwork;2 创建package lab.lab2,并在其中创建一个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中创建一个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中创建一个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题。四、调试分析在调试线程程序的过程中,并干扰到其它应用程序的正常运行,后来经过仔细观察,发现是因为在线程的循环体当中没有调用sleep语句,从而导致线程不断地抢占CPU,从而影响其它程序的正常运行。五、实验结果按照指导书的步骤完成了第1题和第2题,同时编写程序完成了第3题,达到了所要求的实验结果。第3题的源代码如下:/环形队列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中线程的创建有二个方法,特别是runnable 接口的练习。需要在创建线程时候的参数是 runnable 类的对象。七、课后练习1 编写一个多线程程序,该程序主要完成以下工作:(1)生成两个发送线程

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个发送线程int datanum=new intMAX; /每个发送者每次能够发送的数据数int datalength=new intMAX;/每个发送者能

23、够发送的数据总数int datacount=new intMAX; /每个发送者目前已纪发送的数据数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;/该发送线程的数据存储数组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;/发送线程package thread.control;import java.util.Random;public class DataSender extends ThreadDataReciever dr;int id;int datasize; /求平均所需的数据数(M或N)int maxlength; /总共要发送的数据数(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);/与接收线程连接,让接收线程为本发送线程建立数据传送通道(标识,数据数组,每次发送的数据长度,所有数据数)public void run() while (count < maxlength) /数据超过最大数则结束线程int data = 0xFF&generateData();/随机产生一个数据while (!dr.se

29、tData(id, data) /发送数据Thread.yield();System.out.print(""+id+".<"+data+">.");count+;private int generateData() Random r=new java.util.Random();return r.nextInt();/控制类(产生两个发送线程和一个接收线程。)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 编写一个多线程程序,模拟多个售票点联网出售火车票的场景,假设车票有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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论