java - 我应该如何中断和处理java中的一组线程?

标签 java multithreading

我正在编写一个游戏引擎,它在游戏状态下执行 alhpa-beta 搜索,并且我正在尝试并行化它。到目前为止,我所拥有的一开始是有效的,然后它似乎慢慢停止了。我怀疑这是因为我没有正确处理我的线程。

当与计算机对战时,游戏会调用 MultiThreadedComputerPlayer 对象的 getMove() 函数。以下是该方法的代码:

public void getMove(){
    int n = board.legalMoves.size();
    threadList = new ArrayList<WeightedMultiThread>();
    moveEvals = new HashMap<Tuple, Integer>();

    // Whenever a thread finishes its work at a given depth, it awaits() the other threads
    // When all threads are finished, the move evaluations are updated and the threads continue their work.
    CyclicBarrier barrier = new CyclicBarrier(n, new Runnable(){
        public void run() {
            for(WeightedMultiThread t : threadList){
                moveEvals.put(t.move, t.eval);
            }
        }
    });

    // Prepare and start the threads
    for (Tuple move : board.legalMoves) {
        MCBoard nextBoard = board.clone();
        nextBoard.move(move);
        threadList.add(new WeightedMultiThread(nextBoard, weights, barrier));
        moveEvals.put(move, 0);
    }
    for (WeightedMultiThread t : threadList) {t.start();}

    // Let the threads run for the maximum amount of time per move
    try {
        Thread.sleep(timePerMove);
    } catch (InterruptedException e) {System.out.println(e);}
    for (WeightedMultiThread t : threadList) {
        t.stop();
    }

    // Play the best move
    Integer best = infHolder.MIN;
    Tuple nextMove = board.legalMoves.get(0);
    for (Tuple m : board.legalMoves) {
        if (moveEvals.get(m) > best) {
            best = moveEvals.get(m);
            nextMove = m;
        }
    }
    System.out.println(nextMove + " is the choice of " + name + " given evals:");
    for (WeightedMultiThread t : threadList) {
        System.out.println(t);
    }
    board.move(nextMove);
}

这里是相关线程的 run() 方法:

public void run() {
    startTime = System.currentTimeMillis();
    while(true) {
        int nextEval = alphabeta(0, infHolder.MIN, infHolder.MAX);
        try{barrier.await();} catch (Exception e) {}
        eval = nextEval;
        depth += 1;
    }
}

我需要能够在时间到时中断所有线程——我应该如何实现这个?到目前为止,我一直在捕获(并忽略)InterruptedException。

最佳答案

Thread.stop 已被弃用是有原因的。当您在中间中断一个线程时,该线程没有机会正确释放它正在使用的资源,并且不会通知其他线程其完成......这在多线程应用程序中非常重要。我对你表现不佳并不感到惊讶;我敢打赌你的内存使用量会飙升。您也不回收线程,而是在不创建新对象的情况下启动和停止它们,这意味着变量所处的任何损坏状态可能仍然困扰着它们。

更好的方法是设置一个标志来告诉线程它应该返回。因此,在您的 WeightedMultiThread 类中包含一个名为 shouldQuit 之类的 boolean 值,并在每次调用 start() 时将其设置为 false。然后,使用 while (!shouldQuit) 代替 while (true),并使用 t.shouldQuit = true 代替 t.stop()。对每个线程执行此操作后,再进行另一个循环来检查每个线程的 t.isAlive(),一旦每个线程返回,就开始处理您的事务。这样你应该会得到更好的结果。

关于java - 我应该如何中断和处理java中的一组线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13577866/

相关文章:

java - 如何在 ArrayAdapter 中使用带有 4 个不同单选按钮的 Radiogroup

Java:如何在 JFrame 中绘制矩形?

objective-c - 如何在非 ARC 世界中使用 NSMutableDictionary 避免 EXC_BAD_ACCESS?

c#如何让线程等待

C编程,如何在等待用户输入时运行for循环

c++ - 在 UI Thread 中创建对话框导致崩溃

java - jar 中文件的 AsynchronousFileChannel

java - Android动态TabView使用JSON配置文件

java - 转换实现 Runnable 的对象

java - 具有优先级阻塞队列的 ThreadPoolExecutor 不会创建(动态)非核心线程