Tuesday, March 03, 2009

Printing "Hello World" with three different threads

Written a Java program which prints "Hello World" with three different threads ie first thread should print "Hello", second one " " (a space) and the third one should print "World". This three threads can start at any point but our program makes sure that the output is constant.

import java.util.ArrayList;
import java.util.List;

/**
* Program which prints "Hello World", "Hello", " ", and "World" are printed by different threads
* but should be in sequence of "Hello World"
*
* @author mpujari
*/
public class ThreadHelloWorld {

private static final int COUNT = 1000;

private static final String[] STRING_OUT = new String[] { "Hello", " ", "World" };

private static final List stringOutList = new ArrayList(COUNT);

private static class SimpleCountLock {
private int count;

SimpleCountLock(int count) {
this.count = count;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public void incrementCount() {
count++;
}
}

private static class PrinterThread implements Runnable {

private String msg;
private int priority;
private SimpleCountLock lockObj;

public PrinterThread(String msg, int priority, SimpleCountLock lockObj) {
this.msg = msg;
this.priority = priority;
this.lockObj = lockObj;
}

public void run() {
synchronized (lockObj) {
while (true) {
if (this.priority == lockObj.getCount()) {
// System.out.print(msg);
stringOutList.add(msg);

lockObj.incrementCount();
lockObj.notifyAll();
return;
}
try {
lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

public void doTest() {
SimpleCountLock lock = new SimpleCountLock(1);
for (int i = 0; i < COUNT; i++) {
lock.setCount(1);
Thread hello = new Thread(new PrinterThread(STRING_OUT[0], 1, lock));
Thread space = new Thread(new PrinterThread(STRING_OUT[1], 2, lock));
Thread world = new Thread(new PrinterThread(STRING_OUT[2], 3, lock));
Thread[] threads = new Thread[] { space, hello, world};
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public static void main(String[] args) {
ThreadHelloWorld helloWorld = new ThreadHelloWorld();
helloWorld.doTest();
// test the output
int count = 0;
for (String out : stringOutList) {
int mod = count++ % 3;
if (!STRING_OUT[mod].equals(out)) {
System.out.println("STRING_OUT[mod]:" + STRING_OUT[mod] + ", " + out);
throw new RuntimeException("Test failed");
}
}

System.out.println("Test was successfull");
}

}