java并发检查集合是否为空
我有一段代码:
private ConcurrentLinkedQueue<Interval> intervals = new ConcurrentLinkedQueue();
@Override
public void run(){
while(!intervals.isEmpty()){
//remove one interval
//do calculations
//add some intervals
}
}
此代码由特定数量的线程同时执行。正如您所看到的,循环应该继续,直到集合中没有更多的间隔,但是有一个问题。在每次迭代开始时,从集合中删除一个间隔,最后可能会将一些间隔添加回同一集合中
问题是,当一个线程在循环中时,集合可能会变为空,因此试图进入循环的其他线程将无法做到这一点,并将提前完成其工作,即使集合可能在第一个线程完成迭代后填充值。我希望线程数保持不变(或不超过某个数字n),直到所有工作真正完成
这意味着当前没有线程在循环中工作,集合中也没有元素。实现这一目标的可能途径是什么?欢迎任何想法
在我的具体案例中,解决这个问题的一个方法是给每一条线一个不同的原始集合。但是在一个线程完成它的工作之后,程序就不再使用它了,尽管它可以帮助其他线程进行计算,所以我不喜欢这个解决方案,因为在我的问题中利用机器的所有核心是很重要的
这是我能想到的最简单的最小工作示例。这可能太长了
public class Test{
private ConcurrentLinkedQueue<Interval> intervals = new ConcurrentLinkedQueue();
private int threadNumber;
private Thread[] threads;
private double result;
public Test(int threadNumber){
intervals.add(new Interval(0, 1));
this.threadNumber = threadNumber;
threads = new Thread[threadNumber];
}
public double find(){
for(int i = 0; i < threadNumber; i++){
threads[i] = new Thread(new Finder());
threads[i].start();
}
try{
for(int i = 0; i < threadNumber; i++){
threads[i].join();
}
}
catch(InterruptedException e){
System.err.println(e);
}
return result;
}
private class Finder implements Runnable{
@Override
public void run(){
while(!intervals.isEmpty()){
Interval interval = intervals.poll();
if(interval.high - interval.low > 1e-6){
double middle = (interval.high + interval.low) / 2;
boolean something = true;
if(something){
intervals.add(new Interval(interval.low + 0.1, middle - 0.1));
intervals.add(new Interval(middle + 0.1, interval.high - 0.1));
}
else{
intervals.add(new Interval(interval.low + 0.1, interval.high - 0.1));
}
}
}
}
}
private class Interval{
double low;
double high;
public Interval(double low, double high){
this.low = low;
this.high = high;
}
}
}
关于这个程序,你可能需要了解的是:在每次迭代之后,间隔要么消失(因为它太小),要么变小,要么分成两个更小的间隔。没有时间间隔后,工作就完成了。此外,我应该能够用一些数字n来限制执行这项工作的线程的数量。实际的程序通过划分区间并使用一些规则丢弃那些区间中不能包含最大值的部分来寻找某个函数的最大值,但这与我的问题不应该真的相关
共 (0) 个答案