我在使用并行线程时遇到了一些麻烦。我让每个学生上课一个线程,所以每个学生需要要求一个团队。问题是需要同时限制为20个请求。所以我在一个学生手上做了这个:
int MAX = 20;
int ACTUAL = 0;
public boolean thereIsRoom(){
return ACTUAL < MAX;
}
public void requestTeam(Student student){
if(thereIsRoom()){
ACTUAL += 1;
System.out.println(ACTUAL);
for(int x=0; x<teams.size(); x++){
// student does stuff
}
ACTUAL -= 1;
System.out.println(ACTUAL);
}
}
输出如下:
1
stuff
0
1
2
3
4
stuff
.
.
31
以此类推,但我不明白为什么打印时会超过我的限制。怎么能修好呢?有必要让studenthandler再来一根线吗?如果是,那怎么办?
1条答案
按热度按时间r7knjye21#
我不能肯定为什么你会有这种行为,但有一个突出的漏洞在你的线程安全和修复这可能会解决问题。问题是,当
thereIsRoom
当变量AVAILABLE
已更新。这允许一个经典的问题,是如此众所周知,它被赋予自己的名字:种族条件。例如,如果10个学生线程几乎同时尝试加入该类,并且处理器在if测试之后运行代码之前对测试进行排序,那么即使处理完所有可用增量后将超出限制,它们也可以全部加入。
要解决这个问题,测试和增量必须作为一个原子操作来构建。最常见的过程是使用同步。有时也有同步的替代方法。例如,不是让线程直接尝试进入类,而是创建一个队列来处理入口请求,以防止出现竞争条件。
搜索“种族条件”应该会找到许多文章,涵盖处理这个问题的各种策略。