Java Multitasking «Prev 

Java Town Hall Listing

/* Town Hall - An accurate model or social commentary?
 * Town Hall runs as an applet and illustrates multiple threads.
 */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

class SynchronizedQueue extends Vector {
  
  private int   count;
  private boolean started;
  private boolean waiting;
  private int   writers;
  
  SynchronizedQueue() {
    count = 0;
    started = false;
  }
  
  public synchronized void checkIn () {
    started = true;
    count++;
  }
  
  public synchronized void checkOut () {
    count--;
    notify();
  }
  
  public synchronized void enqueue(Object elt) {
    super.addElement(elt);
    notify();
  }
  
  public synchronized boolean anyoneLeft() {
    if (!started) return true;
    if (count > 0) return true;
    else return false;
  }
  
  public synchronized Object dequeue() {
    Object ret;
    while (anyoneLeft() && (super.elementCount == 0)) {
      try {
    wait();
      } catch (InterruptedException x) {
      }
    }
    if (super.elementCount > 0) {
      ret = super.firstElement();
      super.removeElement(ret);
    } else {
      ret = null;
    }
    return ret;
  }
}

class Speaker extends Thread {
  int id;
  int speech_count;
  SynchronizedQueue my_soapbox;
  
  static String nouns[] = {
    "dogs", "cats", "elephants", "donkeys", "houses", 
    "monkeys", "cars", "bicycles", "computers", 
    "music", "books" };
  
     static String ends[] = {
       "outlawed", "banned", "imported", "discouraged", 
       "sold", "bought", "given away", "made mandatory", 
       "encouraged", "deported", "exported" };

  Speaker(int new_id, int turns, SynchronizedQueue forum) {
    id = new_id;
    speech_count = turns;
    my_soapbox = forum;
  }

  public void run() {
    int i;
    Random r = new Random();
    my_soapbox.checkIn();
    my_soapbox.enqueue("speaker "+ id +" stepping onto soapbox");
    for (i = 0; i < speech_count; i++) {
      try {
	  	  sleep((r.nextInt() % 10) * 10);
      } 
	     catch (Exception e) {
        e.printStackTrace();      
	     }
      my_soapbox.enqueue("speaker "+ id +": " + nouns[Math.abs(r.nextInt())%nouns.length] +
      " should be " + ends[Math.abs(r.nextInt())%ends.length]);
    }
    my_soapbox.enqueue("speaker "+ id +" stepping off soapbox");
    my_soapbox.checkOut();
  }
}

class MC extends Thread {
  SynchronizedQueue podium;
  TextArea  ta;
  
  MC(SynchronizedQueue new_forum, TextArea ta) {
    podium = new_forum;
    this.ta = ta;
  }
  
  

  public void run() {
    Object utterance;

    ta.append("MC here: good morning.");
    ta.append("\n");
    
    utterance = podium.dequeue();
    while (utterance != null) {             
      ta.append((String)utterance);
      ta.append("\n");
      utterance = podium.dequeue();
    }
    
    ta.append("MC here: good night.");
    ta.append("\n");
  }
}

public class TownHall extends Applet implements ActionListener{
  boolean    running = false;
  boolean    meetingStarted = false;
  MC         georgeWill;
  TextArea   ta;
  Button gavel, clear;
  public void init() {
    setLayout(new BorderLayout());
    ta = new TextArea(10,50);
    add("Center", ta);

    Panel p = new Panel();
    gavel = new Button("pound the gavel");
    clear = new Button("clear the air");
    gavel.addActionListener(this);
    clear.addActionListener(this);
    p.add(gavel);
    p.add(clear);
    add("South", p);
  }
  public void start() {
    if (!running && meetingStarted) {
      georgeWill.resume();
      running = true;
    }
  }
  
  public void stop() {
    if (running) {
      georgeWill.suspend();
      running = false;
    }
  }
  
  public void destroy() {
    georgeWill.stop();
  }

  
  void startNewMeeting() {   
    int num_speakers = 5;
    SynchronizedQueue podium = new SynchronizedQueue();
    Speaker[] contenders = new Speaker[num_speakers];
    
    georgeWill = new MC(podium, ta);
    georgeWill.start();
    
    running = true;
    meetingStarted = true;
    
    for(int i = 0; i < num_speakers; i++) {
      contenders[i] = new Speaker(i, 10, podium);
      contenders[i].start();
    }
    try {
      georgeWill.join();
    } catch (InterruptedException x) {//throw Exception }
    ta.append("Town Hall closing.");
    ta.append("\n");
   
    georgeWill.stop();
    running = false;
    meetingStarted = false;
  }
  
  public void actionPerformed(ActionEvent e) {
    if(e.getSource() == gavel)
      startNewMeeting();
    else
      ta.setText("");
  }
  
}