/* * Copyright (C) 1998 Ralf Wiebicke * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package de.rw7; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Checkbox; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Panel; import java.awt.Scrollbar; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; abstract class QueueServer extends Panel implements Runnable, ItemListener, AdjustmentListener { protected String title; protected Queue queue; protected boolean running; protected int waiting; protected int maxwait = 0; protected Thread thread; private Checkbox cb; QueueServer(String title, Queue queue, boolean running, int waiting) { super(new BorderLayout()); this.title = title; this.queue = queue; this.running = running; this.waiting = waiting; cb = new Checkbox(title, running); cb.addItemListener(this); cb.setLabel(buildTitle()); add(cb, "North"); Scrollbar sb = new Scrollbar(Scrollbar.HORIZONTAL, waiting, 100, 0, 1000); sb.addAdjustmentListener(this); add(sb, "South"); thread = new Thread(this); thread.setDaemon(true); thread.setPriority(thread.MIN_PRIORITY); thread.start(); } private String buildTitle() { return ( title + " (" + String.valueOf(waiting) + "ms, " + String.valueOf(maxwait) + ")"); } public void itemStateChanged(ItemEvent e) { switch (e.getStateChange()) { case ItemEvent.SELECTED : running = true; thread.resume(); break; case ItemEvent.DESELECTED : running = false; break; default : throw (new IllegalArgumentException()); } } public void adjustmentValueChanged(AdjustmentEvent e) { waiting = e.getValue(); e.getAdjustable().setValue(waiting); cb.setLabel(buildTitle()); } void stop() { if (thread != null) { thread.stop(); thread = null; } } public void run() { try { while (true) { if (!running) thread.suspend(); int n = runQueue(); if (n > maxwait) { maxwait = n; cb.setLabel(buildTitle()); } } } catch (java.lang.InterruptedException e) { System.err.println("interrupt"); } } abstract int runQueue() throws java.lang.InterruptedException; } // class QueueServer class Producer extends QueueServer { Producer(Queue queue, boolean running) { super("Producer", queue, running, 100); } int runQueue() throws java.lang.InterruptedException { Thread.sleep(waiting); return queue.in(); } } class Consumer extends QueueServer { Consumer(Queue queue, boolean running) { super("Consumer", queue, running, 120); } int runQueue() throws java.lang.InterruptedException { Thread.sleep(waiting); return queue.out(); } } class Queue { int capacity, number = 0; Queue(int capacity) { this.capacity = capacity; } synchronized int in() throws java.lang.InterruptedException { int n; for (n = 0; isFull(); n++) wait(); number++; notifyAll(); if (component != null) component.repaint(); return n; } synchronized int out() throws java.lang.InterruptedException { int n; for (n = 0; isEmpty(); n++) wait(); number--; notifyAll(); if (component != null) component.repaint(); return n; } private final boolean isFull() { return (number == capacity); } private final boolean isEmpty() { return (number == 0); } private Component component; public Component getComponent() { if (component != null) return component; component = new Canvas() { private int lastvalue; private Dimension d; private int zoom = 1; public void paint(Graphics g) { d = getSize(); zoom = d.width / capacity; int val = zoom * number; int cap = zoom * capacity; g.fillRect(0, 0, val, d.height); g.clearRect(val, 0, cap - val, d.height); g.fillRect(cap, 0, d.width - cap, d.height); lastvalue = val; } public void update(Graphics g) { int val = zoom * number; if (val > lastvalue) g.fillRect(lastvalue, 0, val - lastvalue, d.height); else g.clearRect(val, 0, lastvalue - val, d.height); lastvalue = val; } }; return component; } // Queue.getComponent } // class Queue public class Concurrent extends java.applet.Applet { Queue q; public void init() { setLayout(new BorderLayout(2, 2)); q = new Queue(70); Panel P = new Panel(); P.setLayout(new GridLayout(0, 1, 2, 2)); P.add(new Producer(q, true)); P.add(new Producer(q, false)); P.add(new Producer(q, false)); add(P, "North"); P = new Panel(); P.setLayout(new GridLayout(0, 1, 2, 2)); P.add(new Consumer(q, true)); P.add(new Consumer(q, false)); P.add(new Consumer(q, false)); add(P, "South"); add(q.getComponent(), "Center"); } }