// add Thread priorities // add busy wait instead of sleep import java.awt.*; import java.awt.event.*; import javax.swing.*; class NewFrame extends JFrame { // For drawing the race results. JPanel drawingArea; public NewFrame () { // Frame properties. this.setTitle ("Dog Race"); this.setResizable (true); this.setSize (600,200); Container cPane = this.getContentPane(); cPane.setLayout (new BorderLayout()); // Quit button. JPanel p = new JPanel (); JButton quitb = new JButton ("QUIT"); quitb.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent a) { System.exit (0); } } ); p.add (quitb); // Pressing "start" calls race() JButton startb = new JButton ("START"); startb.addActionListener (new ActionListener () { public void actionPerformed (ActionEvent a) { race (); } } ); p.add (startb); // Now add the panel to the frame. cPane.add (p, BorderLayout.SOUTH); // A JPanel to draw the results. drawingArea = new JPanel(); drawingArea.setBackground (Color.white); cPane.add (drawingArea, BorderLayout.CENTER); this.setVisible (true); } void race () { // Create two dog instances with different ID's. Dog d1 = new Dog (1, drawingArea, 3, 6, this); Dog d2 = new Dog (2, drawingArea, 3, 6, this); Dog d3 = new Dog (3, drawingArea, 3, 6, this); Dog d4 = new Dog (4, drawingArea, 3, 6, this); Dog d5 = new Dog (5, drawingArea, 3, 6, this); Dog d6 = new Dog (6, drawingArea, 3, 6, this); Dog.startRace(); d1.setPriority(Thread.NORM_PRIORITY); d2.setPriority(Thread.NORM_PRIORITY+3); d3.setPriority(Thread.NORM_PRIORITY); d4.setPriority(Thread.NORM_PRIORITY); d5.setPriority(Thread.NORM_PRIORITY); d6.setPriority(Thread.NORM_PRIORITY); d1.start(); d2.start(); d3.start(); d4.start(); d5.start(); d6.start(); try { d1.join(); d2.join(); d3.join(); d4.join(); d5.join(); d6.join(); Thread.sleep(2000); } catch(Exception e) {} } } class Dog extends Thread { private static final int BIG = 500; private int position = 20; // Starting position. private int ID; // An ID. private JPanel drawingArea; // The panel on which to draw. private int minNap, maxNap; private NewFrame f; private static boolean over; public Dog (int ID, JPanel drawingArea, int min, int max, NewFrame f) { this.f = f; minNap = min; maxNap = max; this.ID = ID; this.drawingArea = drawingArea; // Draw ID on panel. Graphics g = drawingArea.getGraphics (); g.drawString (""+ID, 5, 20*ID+8); drawingArea.repaint(); } public static void startRace() { over = false; } public void nap() { try { Thread.sleep (minNap + (int)(Math.random()*(maxNap-minNap))); } catch (InterruptedException e) { System.out.println (e); } int waste = 0; for (int i = 0; i < BIG*Math.random()*(maxNap-minNap); i++) { waste = 0; for (int j = 0; j < BIG*Math.random()*(maxNap-minNap); j++) waste++; } } public void move () { // Move a random amount. int newPosition = position + (int) (5 + 5*Math.random()); // Draw new position. Graphics g = drawingArea.getGraphics (); int size = newPosition - position; g.fillRect (position, 20*ID, size, 10); position = newPosition; } // Must implement run() to satisfy Runnable interface public void run () { // Compute the finish line distance. int finishLine = drawingArea.getSize().width; // While not complete... while ((position < finishLine) && !raceFinished(false, ID)) { nap(); if (!raceFinished(false, ID)) move (); } if (position >= finishLine) raceFinished(true, ID); } public boolean raceFinished(boolean set, int caller) { if (set) { over = true; System.out.println(ID+" claims victory"); } return over; } } public class Race55 { public static void main (String[] argv) { NewFrame nf; nf = new NewFrame (); } }