天津理工大学Java实验四实验报告.docx
- 文档编号:9343738
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:17
- 大小:451.15KB
天津理工大学Java实验四实验报告.docx
《天津理工大学Java实验四实验报告.docx》由会员分享,可在线阅读,更多相关《天津理工大学Java实验四实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
天津理工大学Java实验四实验报告
天津理工大学
计算机科学与工程学院
实验报告
2017至2018学年第一学期
课程名称
Java语言程序设计
学号
学生姓名
年级
专业
计算机科学与技术
教学班号
实验地点
7-220
实验时间
2017年12月4日第5节至第6节
主讲教师
董玉涛
辅导教师
董玉涛
实验(四)
实验名称
打印机管理器模拟
软件环境
Windows8.1,JavaSE9,JDK8,Eclipse
硬件环境
PC机
实验目的
1.掌握线程创建的方法;
2.掌握线程的基本控制方法;
3.掌握线程间的同步控制方法 ;
4.掌握Java多线程操作。
实验内容(应包括实验题目、实验要求、实验任务等)
本实验要求你使用wait/notify和其他线程控制方法创建一个打印机管理器(printermanager)。
要求你创建几个并发线程产生打印作业,一个打印管理器线程处理这些作业。
下面是一个可能的输出结果:
C:
Printmanagerisstartingup.
C:
Waitingonajobtoprint.
P:
Addingjob'Fred#1'tothequeue
C:
Startingjob'Fred#1'
P:
Addingjob'Elizabeth#1'tothequeue
P:
Addingjob'Simon#1'tothequeue
C:
Completedjob'Fred#1'
C:
Startingjob'Elizabeth#1'
P:
Addingjob'Fred#2'tothequeue
P:
Addingjob'Simon#2'tothequeue
C:
Completedjob'Elizabeth#1'
C:
Startingjob'Simon#1'
P:
Addingjob'Fred#3'tothequeue
C:
Completedjob'Simon#1'
C:
Startingjob'Fred#2'
P:
Addingjob'Elizabeth#2'tothequeue
P:
Addingjob'Simon#3'tothequeue
C:
Completedjob'Fred#2'
C:
Startingjob'Simon#2'
C:
Completedjob'Simon#2'
C:
Startingjob'Fred#3'
P:
Addingjob'Fred#4'tothequeue
C:
Completedjob'Fred#3'
C:
Startingjob'Elizabeth#2'
P:
Addingjob'Fred#5'tothequeue
C:
Completedjob'Elizabeth#2'
C:
Startingjob'Simon#3'
P:
Addingjob'Elizabeth#3'tothequeue
C:
Completedjob'Simon#3'
C:
Startingjob'Fred#4'
C:
Completedjob'Fred#4'
C:
Startingjob'Fred#5'
C:
Completedjob'Fred#5'
C:
Startingjob'Elizabeth#3'
C:
Completedjob'Elizabeth#3'
C:
Waitingonajobtoprint.
C:
Printmanagerishalted.
实验过程与实验结果(可包括实验实施的步骤、算法描述、流程、结论等)
一、实验步骤与算法描述
1、定义PrintJob类
(1)基于上述UML类图定义PrintJob类,代表一个打印作业。
2、定义Producer类
(2)基于上述UML类图定义Producer类。
它必须实现Runnable接口。
(3)写一个构造方法初始化4个实例变量。
(4)run方法必须创建数量为numberOfJobs的打印作业(PrintJob对象)。
根据producerName属性和作业号给每个作业起一个作业名(即jobName=producerName#N)。
每个打印作业的页数pages由sizeOfJobs属性确定。
(5)用Printer对象的addJob方法把打印作业加到打印机管理器的打印队列中去。
该方法可能抛出FullQueueException异常(队列满异常),要求编程时处理这种异常情况,直至队列非满为止,然后把作业加到队列中去。
(6)在相邻两次打印期间,producer睡眠delayBetweenJobs长时间。
3、定义Printer类
(7)基于上述UML类图定义Printer类。
(8)写构造方法初始化属性。
打印队列大小为5,即最多能容纳5个作业。
(9)printQueue属性是一个FIFO队列,它包含所有的被提交的打印作业。
Queue是一个接口,代表FIFO队列。
CircularQueue实现该接口。
FullQueueException和EmptyQueueException异常分别可以由addBack和removeFront方法抛出。
(10)写public、synchronized方法addJob。
该方法可能抛出FullQueueException异常。
在该方法中,加一个作业以后要通知Printer对象可以继续打印。
(11)写private、synchronized方法getJob。
该方法可能抛出EmptyQueueException异常。
(12)写public、synchronized方法halt(停止)。
该方法设置stateIsRunning属性为false。
StateIsRunning属性代表打印机是否正在运行。
(13)写run方法。
它是打印管理器的核心。
它始终处于连续循环之中,直到stateIsRunning=false为止。
它从队列中取打印作业,输出Startingjob‘作业名’,然后处理作业(睡眠一段时间,500毫秒/页×页数),然后打印Completedjob‘作业名’。
如果队列中没有作业,输出Waitingonajobtoprint并等待。
当打印机被halt后,应先处理剩余作业,然后输出Printmanagerishalted并退出run方法。
(14)本题最困难的部分是wait和notify的使用。
4、创建TestPrinter程序
(15)这个类只包含main方法。
(16)让main方法创建3个Producer对象,它们有不同的打印特征:
作业大小(5页-25页),作业间的延迟(2秒-10秒)。
下面是模拟用的三个Producer对象:
producerName
numberOfJobs
sizeOfJobs
delayBetweenJobs
Fred
5
5
8秒
Elizabeth
3
25
20秒
Simon
3
5
10秒
(17)为打印机管理器创建一个线程。
设置它的优先级为最大,然后启动该线程。
(18)为每个producer创建线程,然后启动该线程。
(19)用join方法等待每个producer线程结束。
(20)最后,停止打印机管理器。
二、实验结果截图:
三、实验分析总结
本次实验中,主要练习编译了Java中多线程有关的程序。
通过本次实验,对Java中多线程的实现与控制操作有了更深一步的理解。
以后也还需要多加练习,能更加熟悉。
同时,编写程序中遇到问题再所难免,应耐心探究其中的原因,从出现问题的地方起,并联系前后程序,仔细推敲,逐个排查。
直到最终搞清为止。
附录(源程序清单)
//FullQueueException类
packageEx;
publicclassFullQueueExceptionextendsIndexOutOfBoundsException
{
privatestaticfinallongserialVersionUID=1L;
StringERROR_INFO;
FullQueueException(Strings)
{
this.ERROR_INFO=newString(s);
}
publicStringtoString()
{
return"FullQueueException"+ERROR_INFO;
}
}
//EmptyQueueException类
publicclassEmptyQueueExceptionextendsIndexOutOfBoundsException
{
privatestaticfinallongserialVersionUID=1L;
StringERROR_INFO;
EmptyQueueException(Strings)
{
this.ERROR_INFO=newString(s);
}
publicStringtoString()
{
return"EmptyQueueException"+ERROR_INFO;
}
}
//CircleQueue类
importjava.util.Arrays;
publicclassCircleQueue
{
privateintDEFAULT_SIZE=5;
privateintcapacity;
privateObject[]elementData;
privateintfront=0;
privateintrear=0;
publicCircleQueue()
{
capacity=DEFAULT_SIZE;
elementData=newObject[capacity];
}
publicCircleQueue(Telement)
{
this();
elementData[0]=element;
rear++;
}
publicCircleQueue(Telement,intinitSize)
{
this.capacity=initSize;
elementData=newObject[capacity];
elementData[0]=element;
rear++;
}
publicintsize()
{
if(isEmpty())
{
return0;
}
returnrear>front?
rear-front:
capacity-(front-rear);
}
publicvoidaddBack(Telement)throwsFullQueueException
{
if(rear==front&&elementData[front]!
=null)
{
thrownewFullQueueException("队列已满的异常");
}
elementData[rear++]=element;
rear=rear==capacity?
0:
rear;
}
publicTremoveFront()throwsEmptyQueueException
{
if(isEmpty())
{
thrownewEmptyQueueException("空队列异常");
}
ToldValue=(T)elementData[front];
elementData[front++]=null;
front=front==capacity?
0:
front;
returnoldValue;
}
publicTelement()throwsEmptyQueueException
{
if(isEmpty()){
thrownewEmptyQueueException("空队列异常");
}
return(T)elementData[front];
}
publicbooleanisEmpty()
{
//rear==front且rear处的元素为null
returnrear==front&&elementData[rear]==null;
}
publicvoidclear()
{
Arrays.fill(elementData,null);
front=0;
rear=0;
}
}
//PrintJob类
publicclassPrintJob
{
privateStringjobName;
privateintpages;
publicPrintJob(StringsjN,intspg)
{
this.jobName=newString(sjN);
this.pages=spg;
}
publicStringgetName()
{
returnthis.jobName;
}
publicintgetPages()
{
returnthis.pages;
}
}
//Producer类
importjava.util.Queue;
publicclassProducerimplementsRunnable
{
privateintsizeOfJobs;
privateintnumberOfJobs;
privateintdelayBetweenJobs;
privateStringproducerName;
privateThreadPrintThread=null;
publicProducer(intss,intsn,intsd,Stringspn,Threadt){
this.sizeOfJobs=ss;
this.numberOfJobs=sn;
this.delayBetweenJobs=sd;
this.producerName=newString(spn);
this.PrintThread=t;
}
publicvoidrun(){
for(inti=0;i PrintJobpj=newPrintJob(this.producerName+"#"+i,this.sizeOfJobs); try{ Printer.getInstance().addJob(pj); Thread.sleep(this.delayBetweenJobs); }catch(InterruptedExceptione){ e.printStackTrace(); }catch(FullQueueExceptione){ System.out.println("无法添加打印任务启动Printer"+e); } } } } //Printer类 publicclassPrinterimplementsRunnable { staticprivateCircleQueue staticprivatebooleanstateIsRunning=true; privatestaticfinalPrinterPRNTR_ONLY=newPrinter(); staticprivatebooleanwhileend=false; privatePrinter(){} publicstaticPrintergetInstance(){ returnPRNTR_ONLY; } publicsynchronizedvoidhalt() { if(Printer.stateIsRunning){ System.out.println("C: Printmanagerishalted."); Printer.stateIsRunning=false; } } publicvoidaddJob(PrintJobjob)throwsFullQueueException,InterruptedException { synchronized(printQueue) { try { this.printQueue.addBack(job); } catch(FullQueueExceptione) { try { printQueue.notify(); printQueue.wait(); } catch(InterruptedExceptione1) { e1.printStackTrace(); } } } System.out.println("[1]P: Addingjob"+job.getName()+"tothequeue"); } privatePrintJobgetJob()throwsEmptyQueueException{ PrintJobp=null; synchronized(printQueue){ while(p==null&&stateIsRunning){ try{ p=this.printQueue.element(); Printer.printQueue.removeFront(); }catch(EmptyQueueExceptione){ try{ printQueue.notifyAll(); printQueue.wait(500); }catch(InterruptedExceptione1){ e1.printStackTrace(); } System.out.println("C: Waitingonajobtoprint."+stateIsRunning); } } returnp; } } publicvoidrun(){ System.out.println("C: Printmanagerisstartingup."); while(stateIsRunning){ PrintJobpjob=null; try{ pjob=this.getJob(); System.out.println("[2]C: Startingjob"+pjob.getName()); Thread.sleep(500*pjob.getPages()); System.out.println("[3]C: Completedjob"+pjob.getName()); }catch(EmptyQueueExceptione){ break; }catch(InterruptedExceptione){ e.printStackTrace(); } } } } //TestPrinter类 publicclassTestPrinter { publicstaticvoidmain(String[]args){ PrinterPRNT_P=Printer.getInstance(); ThreadTHRD_P=newThread(PRNT_P); THRD_P.setPriority(10); Producerpd1=newProducer(5,2,5,"A",THRD_P); Producerpd2=newProducer(5,2,5,"B",THRD_P); Producerpd3=newProducer(5,3,5,"C",THRD_P); Threadthrd_A=newThread(pd1); Threadthrd_B=newThread(pd2); Threadthrd_C=newThread(pd3); thrd_A.start(); thrd_B.start(); thrd_C.start(); THRD_P.start(); try{ thrd_A.join(); thrd_B.join(); thrd_C.join(); } catch(InterruptedExceptione1) { e1.printStackTrace(); } try { Thread.sleep(10000); } catch(InterruptedExceptione) { e.printStackTrace(); } PRNT_P.halt(); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 天津 理工大学 Java 实验 报告