标签:
一、 问题描述:
打印机服务程序,采取动态优先级方案,有三种调度策略。
动态优先级方法:
二、打印请求PrintRequest类:
a) 数据成员:
i. private String filename:打印文件名iv. private int waitingTime:等待时间
c) 获取打印页数public int getPageNumber();
d) 计算等待时间public void calcWaitingTime(int t):
当前时间t,waitingTime = t- requestTime
e) 获取等待时间public int getWaitingTime();
f) toString方法。
public class PrintRequest { private String fileName; private int pageNumber; private int requestTime; private int waitingTime; PrintRequest(String fn, int pn, int rt) { this.fileName = fn; this.pageNumber = pn; this.requestTime = rt; } // PrintRequest(PrintRequest pr) { // this.fileName = pr.fileName; // this.pageNumber = pr.pageNumber; // this.requestTime = pr.requestTime; // } public int getPageNumber() { return this.pageNumber; } public void calcWaitingTime(int t) { waitingTime = t-requestTime; } public int getWaitingTime() { return waitingTime; } // public void setPageNumber(int pn) { // this.pageNumber = pn; // } public String toString() { return fileName+" was requested at "+requestTime+" with "+pageNumber+" pages"; } }
三、打印机Printer类:
b) 获取打印机状态public boolean printIdle():返回isIdle;
c) 在t时刻产生r打印请求public boolean printFile(PrintRequest r, int t):
i. 如果当前打印机忙,返回false;
d) 打印一页public int printOnePage():
i. pageLeft减一;
e) 获取当前打印结束的文件public PrintRequest processForOneUnit():
i. 如果打印机空闲, 或者当前正在打印的文档还剩余超过1页则返回 null;public class Printer { private boolean isIdle = true; // private int currTime = 0; // private int startTime; private PrintRequest origJob; private int pageLeft; public boolean printIdle() { return isIdle; } public boolean printFile(PrintRequest r, int t) { if (this.printIdle()) { origJob = r; r.calcWaitingTime(t); pageLeft = r.getPageNumber(); // startTime = currTime; isIdle = false; return true; } else return false; } public int printOnePage() { pageLeft--; if (pageLeft == 0) { isIdle = true; } return pageLeft; } public PrintRequest processForOneUnit() { if (this.printIdle() || pageLeft > 1) { return null; } else return origJob; } public String toString() { if (isIdle) { return "The printer is idle now."; } return origJob+" is working, "+pageLeft+" pages not finished."; } }
四、打印队列PrintQueue类public class PrintQueue<E> extends AbstractQueue<E> implements Queue<E>:
a) 数据成员:
i. private int hasCalledTime = 0:该队列已被访问次数
b) 内部静态私有类private static class Entry<E>:
i. 含有一个元素element,一个next指针指向下一个元素,一个befo指针指向前一个元素;
c) 构造函数PrintQueue(int p):
优先级为p,初始化队首header,header的next和befo分别指向自己,size清零。
d) 获取队列的访问次数public int getCalledTime()和清零队列的访问次数public void resetCalledTime()。
e) 添加元素public boolean add(E e)和public boolean offer(E e):
两者方法相同,只是在e为空的时候add抛出NoSuchElementException的异常,offer返回false。
f) 获取队首元素public E peek()和public E element():
两者方法相同,只是在队列为空的时候element抛出NoSuchElementException的异常,peek返回null。
g) 获取并删除队首元素public E remove()和public E poll():
两者方法相同,只是在队列为空的时候remove抛出NoSuchElementException的异常,poll返回null。import java.util.*; public class PrintQueue<E> extends AbstractQueue<E> implements Queue<E> { private int hasCalledTime = 0; private int size = 0; private int priority; transient private Entry<E> header = new Entry<E>(null, null, null); private static class Entry<E> { E element; Entry<E> next; Entry<E> befo; Entry(E elem, Entry<E> befo, Entry<E> next) { this.element = elem; this.befo = befo; this.next = next; } } PrintQueue(int p) { priority = p; header = new Entry<E>(null, null, null); header.next = header; header.befo = header; size = 0; } public int getCalledTime() { return this.hasCalledTime; } public void resetCalledTime() { this.hasCalledTime = 0; } public boolean add(E e) { if (e == null) { throw new NoSuchElementException(); } Entry<E> tmp = new Entry<E>((E)e, header.befo, header); tmp.befo.next = tmp; header.befo = tmp; size++; return true; } public boolean offer(E e) { if (e == null) { return false; } Entry<E> tmp = new Entry<E>((E)e, header.befo, header); tmp.befo.next = tmp; header.befo = tmp; size++; return true; } public E peek() { if (size == 0) return null; return this.element(); } public E element() { if (size == 0) { throw new NoSuchElementException(); } final Entry<E> tmp = header.next; return tmp.element; } public E poll() { if (size == 0) { return null; } E tmp = (E)(header.next.element); header.next = header.next.next; header.next.befo = header; size--; hasCalledTime++; return tmp; } public E remove() { if (size == 0) { throw new NoSuchElementException(); } return poll(); } public String toString() { String ans = " Priority "+priority+" PrintQueue has been called for "+hasCalledTime+" times, and its size is "+size+"\r\n"; Entry tmp = header.next; for (int i = 0; i < size; i++) { ans += " "+tmp.element.toString()+"\r\n"; tmp = tmp.next; } return ans; } // not use methods: public void clear() { header = new Entry<E>(null, null, null); header.next = header; header.befo = header; size = 0; } public boolean retainAll(Collection c) { return true; } public int size() { return size; } public Iterator<E> iterator() { return new Iterator<E>() { public boolean hasNext() { return true; } public E next() { return (E)(header.next.element); } public void remove() { return; } }; } }
五、打印机调度器PrintDispatcher类public class PrintDispatcher extends AbstractCollection implements Queue:
a) 数据成员:
i. private int queueNumber = 0:内部队列数
b) 内部静态私有类private static class Entry:
该类与PrintQueue基本一致,只是元素element的类型已经确定下来了,为PrintQueue<PrintRequest>。
c) 构造函数PrintDispatcher(int qn, int thre, int t):
i. 指定优先级队列数目qn,调度策略t,访问次数阈值thre;
d) 获取当前优先级最高的任务public PrintRequest peek()和public PrintRequest element():
两者方法基本一致,区别在于如果当前没有等待任务时,peek返回null,而element抛出NoSuchElementException异常。
e) 获取当前优先级最高的任务并从队列中移除public PrintRequest poll ()和public PrintRequest remove /dequeue():
两者方法基本一致,区别在于如果当前没有等待任务时,poll返回null,而remove/dequeue抛出NoSuchElementException异常。
f) 添加新任务public boolean offer/enqueue(Object pr)和public boolean add(Object pr):
两者方法基本一致,区别在于如果pr为空时,offer/dequeue返回false,而add抛出NoSuchElementException异常。
g) 饥饿检测public boolean detectHungry():
i. 遍历每个优先级队列,如果找到一个优先级队列其访问次数tmp.element.getCalledTime()大于threshold,则记录该队列为tmp;import java.util.*; public class PrintDispatcher extends AbstractCollection implements Queue { private int queueNumber = 0; private int type = 0; private int threshold = 0xFFFFFFF; private Entry header = new Entry(null, null, null); private static class Entry { PrintQueue<PrintRequest> element; Entry next; Entry befo; Entry(PrintQueue<PrintRequest> elem, Entry befo, Entry next) { this.element = elem; this.befo = befo; this.next = next; } } PrintDispatcher(int qn, int thre, int t) { queueNumber = qn; type = t; threshold = thre; header = new Entry(null, null, null); header.next = header; header.befo = header; for (int i = 0; i < queueNumber; i++) { PrintQueue<PrintRequest> pq = new PrintQueue<PrintRequest>(i); Entry e = new Entry(pq, header.befo, header); e.befo.next = e; header.befo = e; } } public PrintRequest peek() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.size() > 0) { return tmp.element.peek(); } tmp = tmp.next; } return null; } public PrintRequest element() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.size() > 0) { return tmp.element.peek(); } tmp = tmp.next; } throw new NoSuchElementException(); } public PrintRequest poll() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.size() > 0) { return tmp.element.poll(); } tmp = tmp.next; } return null; } public PrintRequest remove() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.size() > 0) { return tmp.element.remove(); } tmp = tmp.next; } throw new NoSuchElementException(); } public PrintRequest dequeue() { return this.remove(); } public boolean offer(Object pr) { if (pr == null) { return false; } Entry tmp = header.next; int pn; switch (type) { case 0: tmp.element.offer((PrintRequest)pr); break; case 1: pn = (((PrintRequest)pr).getPageNumber()-1)/10; // System.err.println("pr = "+pr); // System.err.println("queueNumber = "+queueNumber); // System.err.println("pn = "+pn); if (pn >= queueNumber) { header.befo.element.offer((PrintRequest)pr); break; } for (int i = 0; i < pn; i++) { tmp = tmp.next; } tmp.element.offer((PrintRequest)pr); break; case 2: pn = (((PrintRequest)pr).getPageNumber())%queueNumber; for (int i = 0; i < pn; i++) { tmp = tmp.next; } tmp.element.offer((PrintRequest)pr); break; } return true; } public boolean add(Object pr) { if (pr == null) { throw new NoSuchElementException(); } return this.offer(pr); } public boolean enqueue(PrintRequest pr) { return this.offer(pr); } public boolean detectHungry() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.getCalledTime() > threshold) { Entry hungryQueue = tmp; for (int j = i+1; j < queueNumber; j++) { hungryQueue = tmp.next; if (hungryQueue.element.size() > 0) { PrintRequest hungryRequest = hungryQueue.element.remove(); // hungry Queue hasCalledTime++ tmp.element.offer(hungryRequest); tmp.element.resetCalledTime(); break; } } return true; } tmp = tmp.next; } return false; } public boolean hasRequestWaiting() { Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { if (tmp.element.size() > 0) { return true; } tmp = tmp.next; } return false; } public String toString() { String ans = ""; Entry tmp = header.next; for (int i = 0; i < queueNumber; i++) { ans += tmp.element.toString()+"\r\n"; tmp = tmp.next; } return ans; } // not use: public Iterator iterator() { return new Iterator() { public boolean hasNext() { return true; } public PrintQueue<PrintRequest> next() { return header.next.element; } public void remove() { return; } }; } public int size() { return queueNumber; } }
六、打印环境模拟PrintSimulation类:
a) 数据成员:
i. private double probability:当前模拟环境中每个时刻产生新打印任务的概率
b) 构造方法PrintSimulation(double p, int n, int k, String a):
i. P为概率,n为队列数,k为阈值,a为优先策略;
c) 生成请求private static PrintRequest generateRequest(double p, int clock, int requestNumber):
i. 产生随机数rnd∈[0,1);
d) 模拟场景public void simulate(int simulateTime):simulateTime为模拟的时间
i. 对每个时刻clock,4. 检测饥饿pd.detectHungry();
5. Clock加一。2. 否则,从调度器pd中取出队首请求pr,放入打印机打印printer.printFile(pr, clock),更新最大等待时间和总等待时间,将pr的页数-等待时间加入waitingTimeArray中;
import java.io.*; import java.util.*; public class PrintSimulation { private double probability; private int queueNumber; private int callThreshold; private char priorityType; ArrayList<Integer[]> waitingTimeArray = new ArrayList<Integer[]>(); int maxWaitingTime = 0; double averageWaitingTime = 0; int sumWaitingTime = 0; PrintDispatcher pd; Printer printer; private static PrintRequest generateRequest(double p, int clock, int requestNumber) { double rnd = Math.random(); if (rnd > p) { return null; } int pagenumber = (int)(1+Math.random()*100); String filename = "Request"+String.valueOf(requestNumber); return new PrintRequest(filename, pagenumber, clock); } PrintSimulation(double p, int n, int k, String a) { probability = p; queueNumber = n; callThreshold = k; priorityType = a.charAt(0); pd = new PrintDispatcher(n, k, a.charAt(0)-'A'); printer = new Printer(); } public void simulate(int simulateTime) { int requestNumber = 0; for (int clock = 0; clock < simulateTime; clock++) { // generate a new PrintRequest PrintRequest newRequest = generateRequest(this.probability, clock, requestNumber); if (newRequest != null) { requestNumber++; System.out.println("New request generated: "+newRequest); pd.enqueue(newRequest); } // printer is idle or not if (!printer.printIdle()) { printer.printOnePage(); } else { if (pd.hasRequestWaiting()) { PrintRequest pr = pd.dequeue(); printer.printFile(pr, clock); //next clock start printing Integer[] pageWaiting = new Integer[]{pr.getPageNumber(), pr.getWaitingTime()}; maxWaitingTime = maxWaitingTime>pr.getWaitingTime() ? maxWaitingTime:pr.getWaitingTime(); sumWaitingTime += pr.getWaitingTime(); waitingTimeArray.add(pageWaiting); } pd.detectHungry(); } System.out.println("Time "+clock+" State:"); System.out.println(pd); System.out.println(printer); } int t = simulateTime; while (pd.hasRequestWaiting() || !printer.printIdle()) { if (!printer.printIdle()) { printer.printOnePage(); } else { PrintRequest pr = pd.dequeue(); printer.printFile(pr, t); Integer[] pageWaiting = new Integer[]{pr.getPageNumber(), pr.getWaitingTime()}; maxWaitingTime = maxWaitingTime>pr.getWaitingTime() ? maxWaitingTime:pr.getWaitingTime(); sumWaitingTime += pr.getWaitingTime(); waitingTimeArray.add(pageWaiting); } System.out.println("Time "+t+" State:"); System.out.println(pd); System.out.println(printer); t++; averageWaitingTime = (double)sumWaitingTime/waitingTimeArray.size(); } } }
七、 结果分析:由DrawResult.java生成
import java.io.*; import java.awt.*; import java.util.*; import java.awt.event.*; import java.text.*; public class DrawResult extends Canvas { ArrayList<PrintSimulation> aps = new ArrayList<PrintSimulation>(); ArrayList<ArrayList<Integer[]>> waitingTimeArray = new ArrayList<ArrayList<Integer[]>>(); ArrayList<Integer> maxWaitingTime = new ArrayList<Integer>(); ArrayList<Double> averageWaitingTime = new ArrayList<Double>(); ArrayList<String[]> storeArgs = new ArrayList<String[]>(); DrawResult() { setSize(800, 600); } public void paint(Graphics g) { int n = Integer.parseInt(storeArgs.get(storeArgs.size()-1)[1]); g.drawLine(100, 500, 730, 500); g.drawString("Page Number/page", 650, 530); g.drawLine(100, 500, 100, 70); g.drawString("Average Waiting Time/ln(AWT)", 50, 50); g.drawString("0", 90, 515); for (int i = 1; i <= n; i++) { g.drawString(String.valueOf(i*(100/n)), 90+i*(600/n), 515); } double ceil = Math.log(maxWaitingTime.get(maxWaitingTime.size()-1)); System.out.println(ceil); int seg = 400/(int)Math.ceil(ceil); for (int i = 1; i <= Math.ceil(ceil); i++) { g.drawString(String.valueOf(i), 80, 500-i*seg); } // change probability // g.drawString("Queue Number = "+n, 500, 300); // g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 320); // g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340); // change queue number // g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300); // g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 320); // g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340); // // change threshold // g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300); // g.drawString("Queue Number = "+storeArgs.get(storeArgs.size()-1)[1], 500, 320); // g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340); // change type g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300); g.drawString("Queue Number = "+storeArgs.get(storeArgs.size()-1)[1], 500, 320); g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 340); g.drawRect(500, 20, 200, 90); System.err.println(storeArgs.get(0)[3]); System.err.println(storeArgs.get(1)[3]); System.err.println(storeArgs.get(2)[3]); for (int j = 0; j <aps.size(); j++) { // change queue number, others should be commented n = Integer.parseInt(storeArgs.get(j)[1]); switch (j) { case 0: g.setColor(Color.RED); break; case 1: g.setColor(Color.BLUE); break; case 2: g.setColor(new Color(0x009966)); break; case 3: g.setColor(new Color(0x660000)); break; case 4: g.setColor(new Color(0xFF9933)); break; default: g.setColor(Color.BLACK); } // // change probability: // g.drawString("Prob="+(new DecimalFormat("0.0").format(0.1+0.1*j)), 510, 40+j*15); // g.drawLine(570, 35+j*15, 680, 35+j*15); // // change queue number: // g.drawString("Queue Number="+(j*2+1), 510, 40+j*15); // g.drawLine(620, 35+j*15, 680, 35+j*15); // change queue number: // g.drawString("Threshold="+(j*5+5), 510, 40+j*15); // g.drawLine(620, 35+j*15, 680, 35+j*15); // change type: g.drawString("Priority Type="+((char)(j+'A')), 510, 40+j*25); g.drawLine(620, 35+j*25, 680, 35+j*25); int[][] averageTime = new int[n][2]; for (int i = 0; i < waitingTimeArray.get(j).size(); i++) { if (storeArgs.get(j)[3].equals("B")) { // System.err.println("page="+waitingTimeArray.get(j).get(i)[0]+", time="+waitingTimeArray.get(j).get(i)[1]); if ((waitingTimeArray.get(j).get(i)[0]-1)/10 >= n) { averageTime[n-1][0] += waitingTimeArray.get(j).get(i)[1]; averageTime[n-1][1] ++; } else { averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/10][0] += waitingTimeArray.get(j).get(i)[1]; averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/10][1] ++; } } else if (storeArgs.get(j)[3].equals("C")) { // System.err.println("C"); // System.err.println("storeArgs.get(j)[3] = "+storeArgs.get(j)[3]); // System.err.println("waitingTimeArray.get(j).get(i)[0] = "+waitingTimeArray.get(j).get(i)[0]); // System.err.println("100/n = "+(100/n)); averageTime[(waitingTimeArray.get(j).get(i)[0]-1)%n][0] += waitingTimeArray.get(j).get(i)[1]; averageTime[(waitingTimeArray.get(j).get(i)[0]-1)%n][1] ++; } else { // System.err.println("A"); averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/(100/n)][0] += waitingTimeArray.get(j).get(i)[1]; averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/(100/n)][1] ++; } } int befox=0, befoy=0; for (int i = 0; i < n; i++) { if (averageTime[i][1] != 0) { averageTime[i][0] /= averageTime[i][1]; } else { averageTime[i][0] = 0; } System.out.println(averageTime[i][0]); g.drawRect(130+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0])), 5, 5); g.drawString(String.valueOf(averageTime[i][0]), 120+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0]))-7); if (befox!=0 && befoy!=0) { g.drawLine(befox, befoy, 130+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0]))); } befox = 130+i*(600/n); befoy = (int)(500-seg*Math.log(averageTime[i][0])); } } } public static void main(String[] args) throws IOException { if (args.length != 4) { System.out.println("The args are illegal!"); } PrintStream pstream = new PrintStream(new FileOutputStream(args[3]+"result.txt")); System.setOut(pstream); Frame frame = new Frame("Result"); DrawResult dr = new DrawResult(); // // change probability: // for (int i = 1 ; i <= 5; i++) { // args[0] = String.valueOf(0.1*i); // PrintSimulation ps = new PrintSimulation(0.1*i, Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]); // ps.simulate(1000); // for (int j = 0; j < ps.waitingTimeArray.size(); j++) { // System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]); // } // System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime); // dr.storeArgs.add(args); // dr.waitingTimeArray.add(ps.waitingTimeArray); // dr.maxWaitingTime.add(ps.maxWaitingTime); // dr.averageWaitingTime.add(ps.averageWaitingTime); // dr.aps.add(ps); // } // // change queue number: // for (int i = 1 ; i <= 10; i+=2) { // args[1] = String.valueOf(i); // System.err.println("n = "+args[1]); // PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]); // ps.simulate(1000); // for (int j = 0; j < ps.waitingTimeArray.size(); j++) { // System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]); // } // System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime); // dr.storeArgs.add(args); // dr.waitingTimeArray.add(ps.waitingTimeArray); // dr.maxWaitingTime.add(ps.maxWaitingTime); // dr.averageWaitingTime.add(ps.averageWaitingTime); // dr.aps.add(ps); // } // // change threshold: // for (int i = 5 ; i <= 25; i+=5) { // args[2] = String.valueOf(i); // System.err.println("n = "+args[2]); // PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]); // ps.simulate(1000); // for (int j = 0; j < ps.waitingTimeArray.size(); j++) { // System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]); // } // System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime); // dr.storeArgs.add(args); // dr.waitingTimeArray.add(ps.waitingTimeArray); // dr.maxWaitingTime.add(ps.maxWaitingTime); // dr.averageWaitingTime.add(ps.averageWaitingTime); // dr.aps.add(ps); // } // change type: for (int i = 0 ; i <= 2; i++) { args[3] = new String(String.valueOf((char)(i+'A'))); System.err.println("type = "+args[3]); PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]); ps.simulate(1000); for (int j = 0; j < ps.waitingTimeArray.size(); j++) { System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]); } System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime); dr.storeArgs.add(new String[]{args[0],args[1],args[2],args[3]}); for (int j = 0; j <= i; j++) { System.err.println("storeArgs: "+dr.storeArgs.get(j)[3]); } dr.waitingTimeArray.add(ps.waitingTimeArray); dr.maxWaitingTime.add(ps.maxWaitingTime); dr.averageWaitingTime.add(ps.averageWaitingTime); dr.aps.add(ps); } frame.add(dr); frame.setLocation(100, 100); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }}); frame.pack(); frame.setVisible(true); } }
而策略B随着页数的增加,平均等待时间在急剧上升。
本文为博主原创,转载请注明来源:
http://blog.csdn.net/cristianojason/article/details/51627993
标签:
原文地址:http://blog.csdn.net/cristianojason/article/details/51627993