// // $Source: /home/cur/djb1/java/threads/RCS/ReadChanWrite.java,v $ // // $Id: ReadChanWrite.java,v 1.3 1996/10/02 15:20:14 djb1 Exp $ // // Multiple Read / Write channels applet // // (C) Copyright 1996 Dave Beckett // University of Kent at Canterbury // import java.awt.*; import java.applet.*; import java.lang.InterruptedException; import Channel; //{{{ class Writer class Writer extends Panel implements Runnable { //{{{ private member data private Thread thread; private Channel chan; private Component comp; private boolean button_clicked; private boolean active; private int id; private static final int delay = 2000; //}}} //{{{ Writer (Channel chan, int id, boolean active) public Writer (Channel chan, int id, boolean active) { this.chan=chan; this.id=id; this.active=active; button_clicked=false; setLayout(new GridLayout(1,1)); String name="Writer "+id; if (!active) { comp = new Label(name, Label.CENTER); } else { comp = new Button(name); } add(comp); } //}}} //{{{ void setLabel (String text) public void setLabel (String text) { if (!active) ((Label)comp).setText(text); else ((Button)comp).setLabel(text); } //}}} //{{{ void run () public void run () { while (Thread.currentThread() == thread) { if (!active || button_clicked) { try { System.out.println ("Writer"+id+": Writing Integer"); setLabel("c ! "+id); repaint(50); chan.write(new Integer(id)); System.out.println ("Writer"+id+": Write done"); Thread.sleep(delay); setLabel("Wrote "+id); repaint(50); Thread.sleep(delay); } catch (InterruptedException e) { break; } button_clicked=false; } else { // nothing } try { Thread.sleep(100); } catch (InterruptedException e) { break; } } } //}}} //{{{ void start () public void start () { if (thread == null) thread = new Thread(this, "Control"); thread.start(); } //}}} //{{{ void stop () public void stop () { thread = null; } //}}} //{{{ boolean action (Event event, Object arg) public boolean action (Event event, Object arg) { if (event.target == comp) { if (!active) { System.out.println ("Writer"+id+": Ignoring button press"); } else { System.out.println ("Writer"+id+": Clicked"); button_clicked = true; } return true; } else { return super.action(event, arg); } } //}}} //{{{ update (Graphics g) public void update (Graphics g) { paint(g); } //}}} } //}}} //{{{ class Reader class Reader extends Panel implements Runnable { //{{{ private member data private Thread thread; private Channel chan; private Component comp; private boolean button_clicked; private boolean active; private int id; private static final int delay = 2000; //}}} //{{{ Reader (Channel chan, int id, boolean active) public Reader (Channel chan, int id, boolean active) { this.chan=chan; this.id=id; this.active=active; button_clicked=false; setLayout(new GridLayout(1,1)); String name="Reader "+id; if (!active) { comp = new Label(name, Label.CENTER); } else { comp = new Button(name); } add(comp); } //}}} //{{{ void setLabel (String text) public void setLabel (String text) { if (!active) ((Label)comp).setText(text); else ((Button)comp).setLabel(text); } //}}} //{{{ void run () public void run () { while (Thread.currentThread() == thread) { if (!active || button_clicked) { try { System.out.println ("Reader"+id+": Reading Integer"); setLabel("c ? "); repaint(50); Object o = chan.read(); System.out.println ("Control"+id+": Read done"); Thread.sleep(delay); setLabel("Read "+o); repaint(50); Thread.sleep(delay); } catch (InterruptedException e) { break; } button_clicked=false; } try { Thread.sleep(100); } catch (InterruptedException e) { break; } } } //}}} //{{{ void start () public void start () { if (thread == null) thread = new Thread(this, "Control"); thread.start(); } //}}} //{{{ void stop () public void stop () { thread = null; } //}}} //{{{ boolean action (Event event, Object arg) public boolean action (Event event, Object arg) { if (event.target == comp) { if (!active) { System.out.println ("Reader"+id+": Ignoring button press"); } else { System.out.println ("Reader"+id+": Clicked"); button_clicked = true; } return true; } else { return super.action(event, arg); } } //}}} //{{{ void update (Graphics g) public void update (Graphics g) { paint(g); } //}}} } //}}} //{{{ class ArrowCanvas class ArrowCanvas extends Canvas { //{{{ private member data static final int inset = 30; static final int arrow_size = 50; //}}} //{{{ void paint (Graphics g) public void paint (Graphics g) { Dimension d=size(); int hheight=d.height/2; int ax=d.width-arrow_size; g.drawLine(inset, hheight+1, d.width-inset, hheight+1); g.drawLine(inset, hheight, d.width-inset, hheight); g.drawLine(inset, hheight-1, d.width-inset, hheight-1); int xpoints[]={ax, d.width-inset, ax}; int ypoints[]={hheight+ arrow_size, hheight, hheight-arrow_size}; g.fillPolygon(xpoints, ypoints, xpoints.length); g.drawString("Channel c", 70, hheight-30); } //}}} } //}}} //{{{ class ReadChanWrite public class ReadChanWrite extends Applet { //{{{ private member data private Label label; private int writer_count = 5; private int reader_count = 5; private boolean writers_active = true; private Writer[] writers; private Reader[] readers; private Panel writers_panel, readers_panel; private ArrowCanvas arrow; private Channel chan; //}}} //{{{ void init() // Called on class load public void init() { System.out.println ("ReadChanWrite:init()"); String param; param = getParameter("READERS"); if (param != null) try { int i = Integer.parseInt(param); if (i>0) reader_count = i; } catch (NumberFormatException e) { String errorMsg = "Parameter READERS parse error in "+param; showStatus(errorMsg); System.err.println(errorMsg); } param = getParameter("WRITERS"); if (param != null) try { int i = Integer.parseInt(param); if (i>0) writer_count = i; } catch (NumberFormatException e) { String errorMsg = "Parameter WRITERS parse error in "+param; showStatus(errorMsg); System.err.println(errorMsg); } param = getParameter("ACTIVE"); if (param != null) { if (param.equals("WRITERS")) { writers_active=true; } else if (param.equals("READERS")) { writers_active=false; } else { String errorMsg = "Parameter ACTIVE error - "+param+" not READERS or WRITERS"; showStatus(errorMsg); System.err.println(errorMsg); } } chan = new Channel(); writers = new Writer[writer_count]; writers_panel = new Panel(); writers_panel.setLayout(new GridLayout(writer_count,1)); for (int i=0; i< writer_count; i++) { writers[i] = new Writer(chan, i, writers_active); writers_panel.add(writers[i]); } readers = new Reader[reader_count]; readers_panel = new Panel(); readers_panel.setLayout(new GridLayout(reader_count,1)); for (int i=0; i< reader_count; i++) { readers[i] = new Reader(chan, i, !writers_active); readers_panel.add(readers[i]); } label = new Label("Channel OF Object between writers (left) and readers (right)"); arrow = new ArrowCanvas(); setLayout(new BorderLayout()); add("North",label); add("West", writers_panel); add("East", readers_panel); add("Center", arrow); // Cause all components to be created validate(); } //}}} //{{{ void stop() // Called on applet pausing public void stop() { System.out.println ("ReadChanWrite:stop()"); for (int i=0; i< writer_count; i++) writers[i].stop(); for (int i=0; i< reader_count; i++) readers[i].stop(); } //}}} //{{{ void start() // Called on applet continuing public void start() { System.out.println ("ReadChanWrite:start()"); for (int i=0; i< writer_count; i++) writers[i].start(); for (int i=0; i< reader_count; i++) readers[i].start(); repaint(); } //}}} //{{{ void destroy() // Called on applet destruction public void destroy() { System.out.println ("ReadChanWrite:destroy()"); for (int i=0; i< writer_count; i++) { writers[i].start(); writers[i] = null; } for (int i=0; i< reader_count; i++) { readers[i].start(); readers[i] = null; } } //}}} //{{{ Insets insets() // Put a little breathing space between the panel and its contents public Insets insets() { return new Insets(5,5,5,5); } //}}} //{{{ String getAppletInfo() public String getAppletInfo() { return "ReadChanWrite by Dave Beckett "; } //}}} //{{{ String[][] getParameterInfo() public String[][] getParameterInfo() { String[][] info = { {"writers", "int", "number of writer processes"}, {"readers", "int", "number of reader processes"}, {"active", "name", "reader or writers active?"}, }; return info; } //}}} } //}}}