Concurrentlinkedqueue未在多线程环境中添加数据

时间:2013-09-11 12:14:50

标签: java multithreading concurrency

在下面的代码中,在非常罕见的情况下(QueueThread对象执行了3亿次)它到达下面提到的if块和queue.size结果是7999.可能的原因是什么。

 if(q.size()<batchsize){   
     System.out.println("queue size" +q.size());   
 }

基本上它无法执行queue.add语句,但执行线程中的所有其他语句。

代码段如下。

import java.util.concurrent.ConcurrentLinkedQueue;   
import java.util.concurrent.ExecutorService;   
import java.util.concurrent.Executors;   
import java.util.concurrent.atomic.AtomicInteger;   

public class CLinkQueueTest {   


    public static final int itersize=100000;   
    public static final int batchsize=8000;   
    public static final int poolsize=100;   

    public static void main (String args[]) throws Exception{   
        int j= 0;   
        ExecutorService service = Executors.newFixedThreadPool(poolsize);   
        AtomicInteger counter = new AtomicInteger(poolsize);   
        ConcurrentLinkedQueue<String> q = new ConcurrentLinkedQueue<String>();   
        String s ="abc";   

        while(j<itersize){   
            int k=0;   
            while(k<batchsize){   
                counter.decrementAndGet();   
                service.submit(new QueueThread(counter, q, s));   
                if(counter.get()<=0){   
                    Thread.sleep(5);   
                }   
                k++;   
            }   
            if(j%20 ==0){   
                System.out.println("Iteration no " + j);   
            }   
            while(counter.get() < poolsize){   
                //wait infinitely   
            }   
            if(q.size()<batchsize){   
                System.out.println("queue size" +q.size());   
            }   
            q.clear();   
            j++;               
        }   

        System.out.println("process complete");   
    }   


import java.util.Queue;   
import java.util.concurrent.Callable;   
import java.util.concurrent.ConcurrentLinkedQueue;   
import java.util.concurrent.atomic.AtomicInteger;   

public class QueueThread implements Callable<Boolean> {   

    private AtomicInteger ai;   
    private Queue<String> qu;   
    private String st;   

    public QueueThread(AtomicInteger i, Queue<String> q, String s){   
        ai = i;   
        qu = q;   
        st = s;        
    }   

    @Override  
    public Boolean call() {   
        try{   
            qu.add(st);            
        } catch(Throwable e){   
            e.printStackTrace();   
        }finally{   
            ai.incrementAndGet();   

        }   
        return true;   
    }   

}  

2 个答案:

答案 0 :(得分:0)

可能是因为Executor还没有完成处理,有一次它在队列中注册一个太少的条目了吗?

很明显,每次调用QueueThread.call()时,都会添加队列,AtomicInteger会递增。我只能想到一个call尚未执行。

也许你可以通过使用类似的东西对系统有点好处:

        while(counter.get() < poolsize){   
            //wait infinitely   
            Thread.currentThread().sleep(5);
        }   

但这只是我的意见。

答案 1 :(得分:0)

ConcurrentLinkedQueue.size方法的文档说:

请注意,与大多数集合不同,此方法不是恒定时间操作。由于这些队列的异步性质,确定当前元素数需要O(n)遍历。 此外,如果在执行此方法期间添加或删除元素,则返回的结果可能不准确。因此,此方法在并发应用程序中通常不是很有用。

相关问题