java - Concurrentlinkedqueue在多线程环境下未命中添加数据

标签 java multithreading concurrency

在下面的代码中,在极其罕见的情况下(10 亿次 QueueThread 对象执行中有 3 次)如果 block 和 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;   
    }   

}  

最佳答案

会不会是有一次在队列中注册的条目太少是因为Executor还没有处理完?

很明显,每次调用 QueueThread.call() 时,都会添加队列,并且 AtomicInteger 会递增。我能想到的是一个 call 没有被执行。

也许你可以通过使用类似的东西对系统更友善一些:

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

但这只是我的意见。

关于java - Concurrentlinkedqueue在多线程环境下未命中添加数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18740934/

相关文章:

java - 为什么要在实体类中实现序列化

java - 如何在多线程中使用等待和通知协议(protocol)

Python:如何在一瞬间进行多个 HTTP POST 查询?

c++ - 何时在 C++ 中使用多线程?

javascript - 如何确保两个客户端不会同时请求破坏状态

java - AtomicIntegerArray 中的数据争用

java - 修改GIF89A文件头

java - 如何编写简单的 JUnit 测试来测试 REST Controller

java - Spring MVC-从 Controller 返回字符串值

JavaFX 使用非 JavaFX 线程的 UI 中使用的提取器更新 ObservableList