在java中为并行线程进行正确的迭代

8yoxcaq7  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(319)

我在使用并行线程时遇到了一些麻烦。我让每个学生上课一个线程,所以每个学生需要要求一个团队。问题是需要同时限制为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再来一根线吗?如果是,那怎么办?

r7knjye2

r7knjye21#

我不能肯定为什么你会有这种行为,但有一个突出的漏洞在你的线程安全和修复这可能会解决问题。问题是,当 thereIsRoom 当变量 AVAILABLE 已更新。这允许一个经典的问题,是如此众所周知,它被赋予自己的名字:种族条件。
例如,如果10个学生线程几乎同时尝试加入该类,并且处理器在if测试之后运行代码之前对测试进行排序,那么即使处理完所有可用增量后将超出限制,它们也可以全部加入。
要解决这个问题,测试和增量必须作为一个原子操作来构建。最常见的过程是使用同步。有时也有同步的替代方法。例如,不是让线程直接尝试进入类,而是创建一个队列来处理入口请求,以防止出现竞争条件。
搜索“种族条件”应该会找到许多文章,涵盖处理这个问题的各种策略。

相关问题