4

2 つのスレッドを使用して、「Hello World Hello World Hello World Hello World Hello World Hello World」と出力する必要があります。

2 つのスレッドで、1 つは「Hello:」を出力し、もう 1 つのスレッドは「World」を出力する必要があります。

これは、hello と world にそれぞれ 1 つずつなど、さまざまなクラスで実行できます。内部クラスでも実行できます。

メイン クラスが 1 つだけで、内部クラスがないようにする方法はありますか?

4

3 に答える 3

1

これはどのように見えますか?特定の単語に対して特定の責任を負うスレッドはありませんが、いくつかの を使用するとAtomic、スレッドがロックステップにあることを簡単に確認できます。

このアルゴリズムは、スレッドが 2 つしかないことに依存していません。ご覧のとおり、この場合は 42 の任意の数のスレッドで機能します。2つでも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();
  }

}
于 2013-04-12T23:45:16.483 に答える
0
  1. T1 が "Hello" を出力し、T2 が "World" を出力したい場合、期待される結果は "Hello World Hello World Hello World Hello World Hello World Hello World " です。

    T1 は最初に開始し、T2 は T1 によって呼び出されます。それ以外の場合は、「World Hello Hello Hello World」を出力として使用できます。

    notify()またはnotifyAll()メソッドを使用して、他のスレッドをウェイクアップすることで、リーダー/ライターまたはプロデューサー/コンシューマー構造をカスタマイズすることをお勧めします。

  2. Runnable インターフェイスと好みの実装を使用して、出力の形式を気にしない場合。

于 2014-01-28T12:31:05.317 に答える