3

これは、学校の OS のクラスでスレッドについて学んだ後 (理論上はヘッ)、マルチスレッドに初めて挑戦したものです。

アルゴリズムが実行されるように設定されているゲームのブランチごとに個別のスレッドを生成することにより、ミニマックス アルゴリズムを並列化しています。これのスケジューリング部分は少しトリッキーです。アルゴリズムは反復的に深化するため、すべてのスレッドで深さの一貫性が必要です。

そのため、最初に、ゲームで使用可能な各移動に対してサブスレッドを生成するマスター スレッドを作成します。

    public void run(){
        // initializes all the threads
        for (AlphaBetaMultiThread t : threadList) {
            t.start();
        }
        try { //This won't ever happen; the subthreads run forever
            evals = 0;
            for (AlphaBetaMultiThread t : threadList) {
                t.join();
                evals += t.evals;
            }
        } catch (Exception e) {
            System.out.println("Error joining threads: " + e);
        }
    }

スレッドは自身をコンストラクターに渡し、各サブスレッドがマスター スレッドの maxDepth プロパティと signalDepth メソッドにアクセスできるようにします。

    public synchronized void signalDepth(){
        signals++;
        if (signals % threadList.length() == 0){
            if (verbose)
                System.out.println(toString());
            depth++;
        }
    }

最後に、サブスレッドの評価プロセスです。残りのスレッドよりも先行している場合は常に、それ自体の優先順位を下げ、すべてのサブスレッドがシグナルを出すまで処理を譲ります。

public void run() {
    startTime = System.currentTimeMillis();
    while(true){
        if (depth >= master.maxDepth) {
            this.setPriority(4);
            this.yield();
            break;
        } else {
            this.setPriority(5);
        }
        eval = -1*alphabeta(0, infHolder.MIN, infHolder.MAX);
        manager.signalDepth();
        depth += 1;
    }
}

私の実装が現在まったく機能していないように見えるという事実に加えて(まだ理由を理解しようとしています)、私がやっていることは物事の標準的な方法ではないように感じます. 私の直感では、私の生活をずっと楽にしてくれるあらゆる種類の組み込みマルチスレッド ライブラリがおそらくあると思いますが、何を探しているのかよくわかりません。

ああ、Thread.destroy() が非推奨であるという警告も表示されます (これは、コンピューター プレーヤーが最終的にその動きを実行した後にすべてを破棄することを計画している方法です)。

私の質問はこれだと思います: サブスレッドを管理するには何を使用すればよいですか?

編集: ああ、私の質問に関連するものが残っている場合は、github で私の完全なコードを自由に見てください: https://github.com/cowpig/MagneticCave 関連ファイルは GameThread と AlphaBetaMultiThread です。無知で申し訳ありません!

別の編集: gamePlayer オブジェクト (マスター スレッドを作成するオブジェクト) が移動を選択する時が来たと判断するまで、スレッドを永遠に反復的に深めていきます。評価。これは、深さの反復ごとに新しいスレッドのセットを作成しない限り、 .join() が機能しないことを意味しますが、それにはさらに多くのオーバーヘッドが必要になるため (私は思う)、実際にそれを行う必要はありません。

4

4 に答える 4

3

あなたの直感は正しいです。Java 5 では、多数の便利な同時実行構造が導入されました。特に調べたいのはCyclicBarrierです。これは、複数のスレッドが相互に待機して共通のバリアポイントに到達できるようにする同期支援です (この場合、それはマスター深度になります)。

于 2012-11-26T03:02:24.457 に答える
1

Thread.join() を使用してサブスレッドを待機する必要があります。サブスレッドは完了したら終了する必要があります。Thread.destroy() はまったく必要なく、優先順位をいじる必要もありません。

于 2012-11-26T02:54:23.217 に答える
0

データフロー グラフ表現がタスクに適している場合は、私のデータフロー ライブラリ df4j を利用できます

于 2012-11-26T05:59:39.290 に答える
0

これには未加工のインスタンスのコレクションを使用する代わりに、インスタンスをThreadに送信する必要があります。すべてのスレッドが何らかの結果を計算している場合は、おそらく and を使用する必要があります。RunnableExecutorServiceCallable<?>ExecutorCompletionService

s の依存関係グラフがある場合は、優れた Guava ライブラリからRunnable使用することをお勧めします。ListenableFuture詳細については、ListenableFuture説明されているwiki 記事を参照してください。

于 2012-11-26T03:03:03.600 に答える