/**************************************************************************
* Copyright (c) 2001 by Punch Telematix. All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* 3. Neither the name of Punch Telematix nor the names of other *
* contributors may be used to endorse or promote products derived *
* from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
* IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE *
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE *
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN *
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
**************************************************************************/
package wonka.test;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
class Carillon extends ThreadGroup {
public final static int MAX_HITS = 20;
public final static int MAX_MISSES = 100;
public static long word_timeout = 1000;
public static long sentence_timeout;
private static Carillon singleton;
private Vector words = new Vector();
private StringBuffer alphabet = new StringBuffer();
public int iterations;
private Carillon(String sentence, int iterations) {
super("Carillon: " + iterations + " of '" + sentence + "'");
this.iterations = iterations;
int i=0;
Enumeration e = new StringTokenizer(sentence);
while (e.hasMoreElements()) {
String nextword = (String)e.nextElement();
words.addElement(nextword);
char nextchar = Character.forDigit(i,36);
alphabet.append(nextchar);
++i;
}
sentence_timeout = word_timeout * i * 2;
demo(words,new String(alphabet));
}
public void uncaughtException(Thread t, Throwable e) {
System.err.println("Carillon: Thread "+t+" threw uncaught exception "+e);
System.err.println("Carillon: terminating");
singleton = null;
this.stop();
}
public static synchronized Carillon getInstance() {
return getInstance("the quick brown fox jumps over the lazy dog",Integer.MAX_VALUE);
}
public static synchronized Carillon getInstance(String sentence) {
return getInstance(sentence,Integer.MAX_VALUE);
}
public static synchronized Carillon getInstance(String sentence, int iterations) {
if (singleton==null) {
singleton = new Carillon(sentence,iterations);
}
return singleton;
}
public synchronized void checkForTermination(int tally) {
if (tally >= iterations) {
ThreadGroup tg = singleton;
tg.stop();
singleton = null;
}
}
public void demo(Vector words, String alphabet) {
Hashtable vocabulary = new Hashtable();
Conductor maestro = new Conductor(this,words,alphabet);
Enumeration kees;
int nwords = words.size();
for (int i = 0; i < nwords; ++i) {
String nextword = (String)words.elementAt(i);
char nextchar = Character.forDigit(i,36);
StringBuffer currentEntry = (StringBuffer)vocabulary.get(nextword);
if (currentEntry==null) {
vocabulary.put(nextword,new StringBuffer(""+nextchar));
}
else {
currentEntry.append(""+nextchar);
}
}
kees = vocabulary.keys();
while (kees.hasMoreElements()) {
String nextword = (String)kees.nextElement();
StringBuffer sequence = (StringBuffer)vocabulary.get(nextword);
Ringer r = new Ringer(maestro,nextword,new String(sequence));
r.setPriority((nextword.hashCode() % 5) + 5);
System.out.println("Starting "+r);
r.start();
}
maestro.start();
}
public static void main(String[] args) {
// getInstance("Multithreaded programming is difficult and error prone. It is easy to make a mistake in synchronization that produces a data race, yet it can be extremely hard to locate this mistake during debugging.");
if (args.length > 0) {
String sentence = args[0];
for (int i = 1; i < args.length; ++i) {
sentence += " " + args[i];
}
getInstance(sentence).setDaemon(true);
}
else {
getInstance().setDaemon(true);
}
}
}