Multithreaded Hello World

Using two streams, you should print "Hello World Hello World Hello World Hello World Hello World Hello World".

In two streams you need to type "Hello: and another stream" World ".

I can do this with different classes, such as one for greetings and peace I can also do this with an inner class

Is there any way that there is only one main class and no inner class?

+3
source share
3 answers

Is there any way that there is only one main class and no inner class?

Sure. You can pass the print string to your main class. Of course, the hard part is to coordinate the streams so that they actually print out "HelloWorld" instead of "WorldHello" or other permutations. The threads will work in parallel, without an order guarantee. The fact that all points of stream programs - they work asynchronously. An attempt to force a specific word to be denied the purpose of using streams.

pompous This brings me a bad job in computer science. The whole point of writing in threads is that they work independently of each other. Coordination usually occurs when each thread is pulled from the work queue and then puts the results in the result queue or something like that. Every time you have a streaming program that needs to coordinate this, you are most likely not going to use streams. & L; / & bombastic GT;

But since everyone is voting, my previous answer, probably because it does not solve the problem of homework, I will add some logic to coordinate between the two threads and spit out "Hello World ...".

Two threads should be able to block something, signal each other and know when they should wait or print. Therefore, I will add boolean printHello and lock the shared lock object, which is passed to:

 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; } } } } } } 
+4
source

What does it look like? None of the threads bears particular responsibility for a particular word, but with the help of the Atomic pair it is easy to ensure that the threads are blocked.

This algorithm does not rely on the fact that there are only two passes - since you can see that it still works with any number of threads, 42 in this case. It will still work fine with only 2 or even 1.

 public class HelloWorld implements Runnable { // The words. private final String[] words; // Which word to print next. private final AtomicInteger whichWord; // Cycles remaining. private final AtomicInteger cycles; private HelloWorld(String[] words, AtomicInteger whichWord, AtomicInteger cycles) { // The words to print. this.words = words; // The Atomic holding the next word to print. this.whichWord = whichWord; // How many times around we've gone. this.cycles = cycles; } @Override public void run() { // Until cycles are complete. while ( cycles.get() > 0 ) { // Must transit from this word int thisWord = whichWord.get(); // to the next word. int nextWord = thisWord + 1; // Are we cycling? boolean cycled = false; if ( nextWord >= words.length ) { // We cycled! cycled = true; // Back to zero. nextWord = 0; } // Grab hold of System.out to ensure no race there either. synchronized ( System.out ) { // Atomically step the word number - must still be at thisWord for the step calculations to still be correct. if ( whichWord.compareAndSet(thisWord, nextWord)) { // Success!! We are the priveliged one! System.out.print(words[thisWord]); // Count the cycles. if ( cycled ) { // Just step it down. cycles.decrementAndGet(); } } } } } public static void test() throws InterruptedException { // The words to print. String [] words = {"Hello ", "world. "}; // Which word to print next (start at 0 obviously). AtomicInteger whichWord = new AtomicInteger(0); // How many cycles to print - 6 as specified. AtomicInteger cycles = new AtomicInteger(6); // My threads - as many as I like. Thread [] threads = new Thread[/*2*/42]; for ( int i = 0; i < threads.length; i++ ) { // Make each thread. threads[i] = new Thread(new HelloWorld(words, whichWord, cycles)); // Start it. threads[i].start(); } // Wait for them to finish. for ( int i = 0; i < threads.length; i++ ) { // Wait for completion. threads[i].join(); } } public static void main(String args[]) throws InterruptedException { System.out.println("HelloWorld:Test"); test(); } } 
+1
source
  • if you want T1 to print "Hello" and T2 to print "World", and your expected result: "Hello World Hello World Hello World Hello World Hello World Hello World"

    T1 starts over, T2 is called by T1, otherwise you can get "World Hello Hello Hello World" as output.

    I suggest notify() up a reader / writer or producer / consumer structure using the notify() or notifyAll() method to wake up other threads.

  • If you don't care about the output format, use the Runnable interface and your preferred implementation.

0
source

All Articles