Is there a way such that there's only one main class and and no inner class?
Sure. You could pass in the string to print into your Main class. Of course the tricky part is to coordinate the threads so they actually print out "HelloWorld"
instead of "WorldHello"
or other permutations. The threads are going to run in parallel with no guarantee of order. That's the whole point of threaded programs -- they run asynchronously. Trying to force a particular word output negates the purpose of using threads.
<rant> This smacks to me of a poorly designed computer science assignment. The whole point of writing with threads is that they run independently in parallel. Coordination typically happens when each thread is pulling from a work queue and then putting results into a results queue or something. Anytime you have a threaded program that needs to coordinate this much, you should most likely not be using threads. </rant>
But, since everyone is down-voting my previous answer probably because it doesn't solve their homework problem perfectly, I'll add some logic to coordinate between the two threads and spit out "Hello World...".
The two threads need to be able to lock on something, signal each other, and know when they should be waiting or printing. So I'll add a boolean printHello
and will lock on a common lock object that is passed in:
public class HelloWorld implements Runnable {
private static boolean printHello = true;
private final String toPrint;
private final boolean iPrintHello;
private final Object lock;
public static void main(String[] args) {
final Object lock = new Object();
// first thread prints Hello
new Thread(new HelloWorld("Hello ", true, lock)).start();
// second one prints World
new Thread(new HelloWorld("World ", false, lock)).start();
}
public HelloWorld(String toPrint, boolean iPrintHello, Object lock) {
this.toPrint = toPrint;
this.iPrintHello = iPrintHello;
this.lock = lock;
}
@Override
public void run() {
// don't let it run forever
for (int i = 0; i < 1000 && !Thread.currentThread().isInterrupted(); ) {
// they need to synchronize on a common, constant object
synchronized (lock) {
// am I printing or waiting?
if (printHello == iPrintHello) {
System.out.print(toPrint);
// switch the print-hello to the other value
printHello = !printHello;
// notify the other class that it can run now
lock.notify();
i++;
} else {
try {
// wait until we get notified that we can print
lock.wait();
} catch (InterruptedException e) {
// if thread is interrupted, _immediately_ re-interrupt it
Thread.currentThread().interrupt();
return;
}
}
}
}
}
}