天津理工大学Java实验四实验报告 - 图文

更新时间:2024-04-19 19:09:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

计算机科学与工程系

天津理工大学

计算机科学与工程学院

实验报告

2017 至 2018 学年 第 一 学期

课程名称 学号 专业 实验时间 主讲教师 辅导教师 董玉涛 董玉涛 计算机科学与技术 Java语言程序设计 学生姓名 教学班号 年级 实验地点 7-220 2017年12月4日 第5节 至 第6节

计算机科学与工程系

实验(四) 实验名称 打印机管理器模拟 软件环境 Windows 8.1,Java SE 9,JDK 8,Eclipse 硬件环境 PC机 实验目的 1. 2. 3. 4. 掌握线程创建的方法; 掌握线程的基本控制方法; 掌握线程间的同步控制方法 ; 掌握Java多线程操作。 实验内容(应包括实验题目、实验要求、实验任务等) 本实验要求你使用wait/notify和其他线程控制方法创建一个打印机管理器(printer manager)。要求你创建几个并发线程产生打印作业,一个打印管理器线程处理这些作业。 下面是一个可能的输出结果: C: Print manager is starting up. C: Waiting on a job to print. P: Adding job 'Fred#1' to the queue C: Starting job 'Fred#1' P: Adding job 'Elizabeth#1' to the queue P: Adding job 'Simon#1' to the queue C: Completed job 'Fred#1' C: Starting job 'Elizabeth#1' P: Adding job 'Fred#2' to the queue P: Adding job 'Simon#2' to the queue C: Completed job 'Elizabeth#1' C: Starting job 'Simon#1' P: Adding job 'Fred#3' to the queue C: Completed job 'Simon#1' C: Starting job 'Fred#2' P: Adding job 'Elizabeth#2' to the queue P: Adding job 'Simon#3' to the queue

2

计算机科学与工程系

C: Completed job 'Fred#2' C: Starting job 'Simon#2' C: Completed job 'Simon#2' C: Starting job 'Fred#3' P: Adding job 'Fred#4' to the queue C: Completed job 'Fred#3' C: Starting job 'Elizabeth#2' P: Adding job 'Fred#5' to the queue C: Completed job 'Elizabeth#2' C: Starting job 'Simon#3' P: Adding job 'Elizabeth#3' to the queue C: Completed job 'Simon#3' C: Starting job 'Fred#4' C: Completed job 'Fred#4' C: Starting job 'Fred#5' C: Completed job 'Fred#5' C: Starting job 'Elizabeth#3' C: Completed job 'Elizabeth#3' C: Waiting on a job to print. C: Print manager is halted.

3

计算机科学与工程系

实验过程与实验结果(可包括实验实施的步骤、算法描述、流程、结论等) 一、 实验步骤与算法描述 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为止。它从队列中取打印作业,输出Starting job ‘作业名’,然后处理作业(睡眠一段时间,500毫秒/页×页数),然后打印Completed job ‘作业名’。如果队列中没有作业,输出Waiting on a job to print并等待。当打印机被halt后,应先处理剩余作业,然后输出Print manager is halted并退出run方法。 (14)本题最困难的部分是wait和notify的使用。 4、创建TestPrinter程序 (15)这个类只包含main方法。 (16)让main方法创建3个Producer对象,它们有不同的打印特征:作业大小

4

计算机科学与工程系

(5页-25页),作业间的延迟(2秒-10秒)。下面是模拟用的三个Producer对象: producerName Fred Elizabeth Simon numberOfJobs 5 3 3 sizeOfJobs 5 25 5 delayBetweenJobs 8秒 20秒 10秒 (17)为打印机管理器创建一个线程。设置它的优先级为最大,然后启动该线程。 (18)为每个producer创建线程,然后启动该线程。 (19)用join方法等待每个producer线程结束。 (20)最后,停止打印机管理器。 二、 实验结果截图: 5

计算机科学与工程系

三、 实验分析总结 本次实验中,主要练习编译了Java中多线程有关的程序。通过本次实验,对Java中多线程的实现与控制操作有了更深一步的理解。以后也还需要多加练习,能更加熟悉。同时,编写程序中遇到问题再所难免,应耐心探究其中的原因,从出现问题的地方起,并联系前后程序,仔细推敲,逐个排查。直到最终搞清为止。 附录(源程序清单)

// FullQueueException类 package Ex;

public class FullQueueException extends IndexOutOfBoundsException { private static final long serialVersionUID = 1L; String ERROR_INFO; FullQueueException(String s) { this.ERROR_INFO = new String(s); } public String toString() { return \ } }

// EmptyQueueException类

public class EmptyQueueException extends IndexOutOfBoundsException { private static final long serialVersionUID = 1L; String ERROR_INFO; EmptyQueueException(String s) { this.ERROR_INFO = new String(s); } public String toString() { return \ } }

// CircleQueue类

import java.util.Arrays;

public class CircleQueue { private int DEFAULT_SIZE = 5;

6

计算机科学与工程系

private int capacity; private Object[] elementData; private int front = 0; private int rear = 0; public CircleQueue() { capacity = DEFAULT_SIZE; elementData = new Object[capacity]; }

public CircleQueue(T element) { this(); elementData[0] = element; rear++; }

public CircleQueue(T element, int initSize) { this.capacity = initSize; elementData = new Object[capacity]; elementData[0] = element; rear++; }

public int size() { if (isEmpty()) { return 0; } return rear > front ? rear - front : capacity - (front - rear); }

public void addBack(T element) throws FullQueueException { if (rear == front && elementData[front] != null) { throw new FullQueueException(\队列已满的异常\ } elementData[rear++] = element; rear = rear == capacity ? 0 : rear; }

public T removeFront() throws EmptyQueueException { if (isEmpty()) { throw new EmptyQueueException(\空队列异常\

7

计算机科学与工程系

} T oldValue = (T) elementData[front]; elementData[front++] = null; front = front == capacity ? 0 : front; return oldValue; }

public T element() throws EmptyQueueException { if (isEmpty()) { throw new EmptyQueueException(\空队列异常\ } return (T) elementData[front]; }

public boolean isEmpty() { // rear==front且rear处的元素为null return rear == front && elementData[rear] == null; }

public void clear() { Arrays.fill(elementData, null); front = 0; rear = 0; } }

// PrintJob类

public class PrintJob { private String jobName; private int pages; public PrintJob(String sjN, int spg) { this.jobName = new String(sjN); this.pages = spg; } public String getName() { return this.jobName; } public int getPages() { return this.pages; } }

8

计算机科学与工程系

// Producer类

import java.util.Queue;

public class Producer implements Runnable { private int sizeOfJobs; private int numberOfJobs; private int delayBetweenJobs; private String producerName; private Thread PrintThread = null; public Producer(int ss, int sn, int sd, String spn, Thread t) { this.sizeOfJobs = ss; this.numberOfJobs = sn; this.delayBetweenJobs = sd; this.producerName = new String(spn); this.PrintThread = t; } public void run() { for (int i = 0; i < this.numberOfJobs; i++) { PrintJob pj = new PrintJob(this.producerName + \ try { Printer.getInstance().addJob(pj); Thread.sleep(this.delayBetweenJobs); } catch (InterruptedException e) { e.printStackTrace(); } catch (FullQueueException e) { System.out.println(\无法添加打印任务 启动 Printer\ } } } }

//Printer类

public class Printer implements Runnable { static private CircleQueue printQueue = new CircleQueue(); static private boolean stateIsRunning = true; private static final Printer PRNTR_ONLY = new Printer(); static private boolean whileend = false; private Printer() {} public static Printer getInstance() { return PRNTR_ONLY; } public synchronized void halt()

9

计算机科学与工程系

{ if (Printer.stateIsRunning) { System.out.println(\ Printer.stateIsRunning = false; } } public void addJob(PrintJob job) throws FullQueueException, InterruptedException { synchronized (printQueue) { try { this.printQueue.addBack(job); } catch (FullQueueException e) { try { printQueue.notify(); printQueue.wait(); } catch (InterruptedException e1) { e1.printStackTrace(); } } } System.out.println(\ } private PrintJob getJob() throws EmptyQueueException { PrintJob p = null; synchronized (printQueue) { while (p == null && stateIsRunning) { try { p = this.printQueue.element(); Printer.printQueue.removeFront(); } catch (EmptyQueueException e) { try { printQueue.notifyAll(); printQueue.wait(500); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println(\

10

计算机科学与工程系

} } return p; } } public void run() { System.out.println(\ while (stateIsRunning) { PrintJob pjob = null; try { pjob = this.getJob();

System.out.println(\ Thread.sleep(500 * pjob.getPages()); System.out.println(\ } catch (EmptyQueueException e) { break; } catch (InterruptedException e) { e.printStackTrace(); } } } }

//TestPrinter类

public class TestPrinter { public static void main(String[] args) { Printer PRNT_P = Printer.getInstance(); Thread THRD_P = new Thread(PRNT_P); THRD_P.setPriority(10); Producer pd1 = new Producer(5, 2, 5, \ Producer pd2 = new Producer(5, 2, 5, \ Producer pd3 = new Producer(5, 3, 5, \ Thread thrd_A = new Thread(pd1); Thread thrd_B = new Thread(pd2); Thread thrd_C = new Thread(pd3); thrd_A.start(); thrd_B.start(); thrd_C.start(); THRD_P.start(); try { thrd_A.join(); thrd_B.join(); thrd_C.join();

11

}

catch (InterruptedException e1) {

e1.printStackTrace(); } try { Thread.sleep(10000); }

catch (InterruptedException e) { e.printStackTrace(); } PRNT_P.halt(); } }

计算机科学与工程系

12

本文来源:https://www.bwwdw.com/article/1o2p.html

Top