私は非常に長い計算を実行でき、中断しなければならないプログラムを開発しています(Traveling Salesman Problem)。パフォーマンスを得るために、実行中のマシン上に論理コアと同じ数のスレッドを使用したいと思います。マルチスレッドの中断可能な連続計算を実行する最適な方法は何ですか?
私の問題は、私が扱っている方法が最善であるかどうかはわかりません。各スレッドは、タイムアウトまで最良の計算された解を返さなければなりません。私の並列コードは100行のコードを持っているので、スレッドのメインループでスレッドが何度か中断されたかどうかを調べることは優雅です。瞬間のために
、これを達成するために、私はそのようなことを考えていた:私たちはここに何
int countThreads = Runtime.getRuntime().availableProcessors();
List<Solution> solutions = new ArrayList<Solution>(countThreads);
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(countThreads + 1);
//Thread that cancel all the other one after the timeout
executor.schedule(new Runnable() {
@Override
public void run() {
executor.shutdownNow();
}
}, timeMax, TimeUnit.SECONDS);
//Threads that compute
for(int i = 0; i < countThreads; i++) {
Solution currentSolution = new Solution();
solutions.add(currentSolution);
ThreadedSolutionFinder solutionFinder =
new ThreadedSolutionFinder(seed, instance, currentSolution);
executor.submit(solutionFinder);
}
// The main thread waits
try {
executor.awaitTermination(timeMax, TimeUnit.SECONDS);
} catch (InterruptedException e) {}
System.out.println("All tasks terminated");
//Iterate over all the found solutions and find the best
//...
を、ということがメインスレッド、スレッドごとにインスタンス化する一つの解決策であるとスレッドの引数としてそれを与えますコンストラクタ。これらのスレッドのrun()メソッドは、指定されたソリューションを入力します。
しかし、shutdownNow()コマンドの後のスレッドは、Thread.interrupted()をチェックしてメインスレッドのawaitTermination()が十分に持続しないと実行を続けることができます。これは、ベストを見つけるためにすべてのソリューションを反復処理するときの並行性アクセスを意味します。
私はこのデザインでは納得できません。幾人かのアイディアがありますか?
私はそれにも納得できません。なぜ、 'executor.submit(...)'によって返された先物を集めて、それらが完了するのにXよりも長い時間がかかると取り消すのはなぜですか? –
各スレッドは、中断された場合でもソリューションを返さなければならないからです。計算に数分かかることがあり、プログラムは2秒後に中断することができます。実際、各スレッドはランダムな解を生成しますが(速いですが)、解を最適化するため、このステップは非常に遅いです。 –
中断された場合はどのような結果を返せますか? –