这是我在学校的操作系统课上学习线程(理论上,呵呵)后第一次尝试多线程,我认为我做我想做的事情的方式是不好的做法/草率。
我通过为设置运行该算法的游戏的每个分支生成一个单独的线程来并行化一个极小极大算法。这其中的调度部分有点棘手。随着算法迭代地加深,我希望所有线程的深度保持一致。
所以,首先我有一个主线程,它为游戏中的每个可用动作生成一个子线程:
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() 将不起作用,除非我为每个深度迭代创建一组新的线程,但是那将需要更多的开销(我认为)所以我真的不想这样做。