这是我在学校的操作系统课程中学习了线程(理论上)之后尝试进行多线程的第一次尝试,我认为我处理它的方式是不好的实践/笨拙。
我通过在算法设置游戏的每个分支上生成一个单独的线程来并行化极小化算法。这里的调度部分有一点棘手;由于算法迭代加深,我希望所有线程之间具有深度一致性。
因此,首先我有一个主线程,它为游戏中的每个可用移动生成一个子线程:
线程将自身传递给构造函数,以便每个子线程都可以访问主线程的maxDepth属性和signalDepth方法。
除了我的实现似乎现在根本不起作用(我还在努力弄清楚为什么),我真的感觉我所做的事情并不是标准的做法。我直觉认为可能有各种内置的多线程库可以让我的生活变得更容易,但我不知道我在寻找什么。
我通过在算法设置游戏的每个分支上生成一个单独的线程来并行化极小化算法。这里的调度部分有一点棘手;由于算法迭代加深,我希望所有线程之间具有深度一致性。
因此,首先我有一个主线程,它为游戏中的每个可用移动生成一个子线程:
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()不起作用,除非我为每个深度迭代创建一组新的线程,但那将需要更多的开销(我认为),所以我不想这样做。