1

大量のデータを取得するために db-hit を実行する 2 つの関数があります。2 つの関数が (同じスレッドによって) 次々に実行されるため、所要時間は T(f(1)) + T(f(2)) です。合計時間が T(max(T(f1), T(f2)) になるように (2 つのスレッドを作成して) 2 つの関数を並列に実行するにはどうすればよいですか

完全な Java Swing アプリケーションの作成が完了し、今すぐパフォーマンスを最適化したいと考えています。洞察に感謝し、質問があまりにも素朴すぎる場合は言い訳をしてください。

ありがとうございました!

4

2 に答える 2

4

関数からの戻り値が必要かどうかは述べていませんが、データベースにアクセスするという事実を考えると、その可能性は非常に高いようです。これに対する非常に優れた簡単な解決策は、Executor と Future を使用することです。

完全なコード例は次のとおりです。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class FuturesExample {

  public interface ReturnTypeOne {}
  public interface ReturnTypeTwo {}

  public void runTwo() {
    ExecutorService executor = Executors.newFixedThreadPool(2);

    // Dispatch two tasks.
    Future<ReturnTypeOne> first = executor.submit(new Callable<ReturnTypeOne>() {
      @Override
      public ReturnTypeOne call() throws Exception {
        // Work, work, work...
        return null;
      }
    });
    Future<ReturnTypeTwo> second = executor.submit(new Callable<ReturnTypeTwo>() {
      @Override
      public ReturnTypeTwo call() throws Exception {
        // Work, work, work...
        return null;
      }
    });

    // Get the results.
    try {
      ReturnTypeOne firstValue = first.get();
      ReturnTypeTwo secondValue = second.get();
      // Combine the results.
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
  }
}

これは 2 つのセクションで構成されています。最初に、2 つのタスクがスレッド プールに送信されます。各 ExecutorService.submit() 呼び出しは、タスク計算の将来の値をすぐに返します。タスクは submit() 呼び出しですぐにディスパッチされ、バックグラウンドで実行されます。もちろん、2 つ以上のタスクをディスパッチすることもできます。

2 番目のセクションでは、先物の値が取得されます。Future.get() の呼び出しは、値が計算されるまで現在のスレッドをブロックします。いずれかのタスクがブロックされているわけではありません。それらはすべて実行されており、スレッドは特定のタスクが完了して値を返すまで待機します。最初の値が返されると、2 番目の Future.get() 呼び出しが行われます。この場合、ブロックする場合とブロックしない場合があります。2 番目のタスクが既に (おそらく最初のタスクの前に) 終了している場合、値はすぐに返されます。2 番目のタスクがまだ実行中の場合、呼び出しは値が計算されるまで現在のスレッドをブロックします。

上記の要約は、メインスレッドが最も長く実行されているタスクの間だけ待機するということです。必要なものだけ。

于 2012-10-11T04:54:22.327 に答える
1

次のように 2 つのスレッドをディスパッチできます。

new Thread(new Runnable()
{
    @Override
    public void run()
    {
        // TODO Place your "f(1)" code here...

    }
}).start();

new Thread(new Runnable()
{
    @Override
    public void run()
    {
        // TODO Place your "f(2)" code here...

    }
}).start();
于 2012-10-04T18:25:16.827 に答える