0

基本的に同じ一連のステップを2回行うクラスがあります。プログラムをどこでマルチスレッド化するかの完璧な例のように思えます。私の質問は、2 つのスレッドだけでこれを実行できるかどうかです。これが物事の一般的な要旨です

Tester implements Runnable{
    Thread obj1Thread, obj2Thread;
    MyObj obj1, obj2;
    String obj1Results, obj2Results;

    void runTests(){
        obj1Thread = new Thread(this, "ob1 thread");
        obj2Thread = new Thread(this, "ob2 thread");
        obj1.start();//builds up obj1
        obj2.start();//builds up obj2
        if(obj1 and obj2 are finished building){
            System.out.println(obj1);
            System.out.println(obj2);
        }
        obj1Thread.startSecondPhase()//runs a separate function that tests obj1 vs ob2. Essentially test(ob1, ob2)
        obj2Thread.startSecondPhase()//runs a separate function that tests obj2 vs ob1. Essentially test(ob2, ob1)
        if(obj1 and obj2 are finished testing){
            System.out.println(obj1Results);
            System.out.println(obj2Results);
        }     
    }
}

最初の部分 - オブジェクトの構築 - が機能しました。私の質問は今 -

  1. 2 つのスレッドが最初の部分を終了するまでメイン スレッドを待機させるにはどうすればよいですか? おそらく、メインはwait両方のオブジェクトに対して a を実行し、スレッドの後でnotifyAllメイン スレッドを待機しますか? では、スレッドはどのようにしてメイン スレッドを取得するのでしょうか。おそらくthis
  2. 新しいスレッドと新しい特定の run 関数を使用して新しいクラスを作成せずに、run 関数のこの「第 2 フェーズ」を使用するにはどうすればよいですか? 小さなタスクごとに新しいクラスとすべてを作成する必要はありません。

私が具体的に望んでいる一連のイベントを明確にするためには -

  1. メイン スレッドが 2 つのスレッドを初期化して開始する
  2. 両方のスレッドがそれぞれのオブジェクトを同時に構築します
  3. 両方のスレッドの構築が完了すると、一時停止します。次に、メインスレッドがオブジェクトを順番に出力します。
  4. メイン スレッドが完了した後、2 つのスレッドはコードをテスト フェーズに同時に進めます。
  5. スレッドが完了すると、メイン スレッドが結果を出力します。おそらくjoin()ここを使用できます

編集:また、特定のスレッドにどのオブジェクトを処理させたいかをどのように伝えることができますか? 現在、私はちょっとハックな方法でそれをやっています(私はスレッド名に取り組んでいます)。

4

1 に答える 1

2

高レベルの抽象化を使用します:ExecutorService.invokeAll(Collection<? extends Callable<T>> tasks)のリストを返す実行およびを使用しますFuture

あなたのメインスレッドは

  1. 2 つのタスクをディスパッチし、
  2. 2 つの先物を取得し、
  3. 結果を印刷してから
  4. さらに 2 つのタスクをディスパッチする

Executor サービスと先物は、内部ですべての同時実行を処理します。

編集

あなたのコメントを見ました:

基本的に1行のコードを実装するためだけの特別な Runnable クラス? 私は理想主義的すぎるかもしれませんが、それは私には間違っていると感じています。

このような場合は通常、匿名の内部クラスを使用します。

Future future = executorService.submit(new Runnable() {
    public void run() {
        System.out.println("Asynchronous task");
    }
});

それは何も悪いことではありません。Java にラムダがあると、さらに短くなります。

  Future future = executorService.submit(() -> {System.out.println("Asynchronous task");});
于 2013-07-02T06:04:53.363 に答える