Threads2 (other files are same as Threads1)
File: java/Threads2/Main.java
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
* Main program for Threads demo
*/
public class Main extends JFrame {
/** Our Row's */
private Vector<Row> rows = new Vector<Row> ();
public static void main (String [] args) {
new Main ();
}
public Main () {
// Window setup
setSize (500, 500);
Container content = getContentPane();
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
// Our canvas
MyCanvas canvas = new MyCanvas (this);
content.add (canvas);
// Show our window
setVisible (true);
// First create our Supply row
SupplyRow supply = new SupplyRow (new Rectangle (10, 10, 500-40, 40),
canvas);
rows.add (supply);
// Now create our regular ConsumerRow's and start() them
for (int i=0; i<5; i++) {
Row r = new ConsumerRow (new Rectangle (10, 100+i*75, 500-40, 40),
canvas, supply);
rows.add (r);
}
}
public void drawCanvas (Graphics g) {
// Draw each of our Row's
for (Row r: rows) r.draw (g);
}
}
File: java/Threads2/Row.java
import java.awt.*;
import java.util.*;
/**
* This is now just an abstract base class
* for SupplyRow and ConsumerRow
*/
abstract public class Row {
protected MyCanvas canvas;
protected Rectangle loc;
protected Vector<Box> boxes = new Vector<Box> ();
public Row (Rectangle loc, MyCanvas canvas) {
this.loc = loc;
this.canvas = canvas;
}
public void draw (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.draw (loc);
// We tell each Box where to draw itself
int boxsize = loc.height-2*5;
Rectangle boxloc = new Rectangle (loc.x+10, loc.y+5,
boxsize, boxsize);
// Draw each of our Box's
for (Box b: boxes) {
b.draw (g, boxloc);
boxloc.x = boxloc.x + boxsize + 10;
}
}
}
File: java/Threads2/ConsumerRow.java
import java.awt.*;
import java.util.*;
/**
* This is like the old plain Row
*/
public class ConsumerRow extends Row implements Runnable {
private SupplyRow supply;
public ConsumerRow (Rectangle loc, MyCanvas canvas, SupplyRow supply) {
super (loc, canvas);
this.supply = supply;
// Start a new thread to run us
Thread thread = new Thread (this);
thread.start();
}
/**
* Method for Runnable
* Thread quits when it can't get another box
*/
public void run () {
while (true) {
// Try and get another box
Box b = supply.take ();
// If no more boxes, quit loop (and hence thread)
if (b==null) break;
boxes.add (b);
// Since we just added to our list, need repaint
canvas.repaint ();
try {
Thread.currentThread().sleep (1000); // 1 second
} catch (InterruptedException e) { }
}
System.out.println ("Row at y = " + loc.y + " finished");
}
}
File: java/Threads2/SupplyRow.java
import java.awt.*;
import java.util.*;
/**
* SupplyRow starts with fixed list of Box's and gives them away,
* is not a process
*/
public class SupplyRow extends Row {
public SupplyRow (Rectangle loc, MyCanvas canvas) {
super (loc, canvas);
// Our initial set of boxes
for (int i=0; i<22; i++) {
boxes.add (new Box ());
}
}
/**
* Give away one of our boxes
* Need a single, "synchronized" routine
* that reports whether we have any to give
* AND takes it ("test and set")
* So this routine tries to give a box,
* returns the Box if succeeds, or null if fails
*/
public synchronized Box take() {
if (boxes.size()>0) {
Box ans = (Box) boxes.remove (0);
// Since we just decreased our list, need repaint
canvas.repaint ();
return ans;
}
else return null;
}
}