我正在尝试轮询 ArrayBlockingQueue 以获取项目:
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()){
closeAppender();
break;
}
if (!TASK_BUFFER.isEmpty() && !TASK_ADDRESS.isEmpty() && !TASK_MARKER.isEmpty()){
buffer = TASK_BUFFER.poll();
remoteAdd = TASK_ADDRESS.poll();
marker = TASK_MARKER.poll();
//ArrayBlockingQueue generating garbage internally??
if (buffer.hasArray()){ //if byte buffer is used just get array
byteArr = buffer.array();
}else{
byteArr = directArr; //if direct buffer is used, we get into direct arr
// Arrays.fill(byteArr, (byte)0); //reset every value to "null" value
buffer.get(byteArr, 0, buffer.remaining());
}
remaining = buffer.remaining();
runTask();
BUFFER_POOL.returnBuffer(buffer);
}
}
LOGGER.info(mainMarker,"Task Scheduler Thread has terminated...");
}
但是,当我运行 jvisualvm 时,我可以看到每次轮询时它都在分配字节。我试过注释和取消注释代码的其他部分,但只有轮询会影响分配的字节。我已经检查了这个 link 但我不想迭代整个数组。我希望一次处理一个项目然后将其删除。处理这个问题的正确方法是什么?
edit:我有一个单独的线程“生成”ByteBuffer、InetSocketAddress 和 Marker 的实例,并将其放入 arrayblockingqueues 中。我还检查了 poll() 和 dequeue() 的源代码,它似乎没有做任何应该保证字节分配的事情
构造函数如下所示:
private final BlockingQueue<ByteBuffer> TASK_BUFFER;
private final BlockingQueue<InetSocketAddress> TASK_ADDRESS;
private final BlockingQueue<Marker> TASK_MARKER;
private final BufferPool BUFFER_POOL;
private final ExcerptAppender APPENDER;
public TaskScheduler(BufferPool bufferPool, ChronicleQueue chronicleQueue){
TASK_BUFFER = new ArrayBlockingQueue<>(bufferPool.getCapacity());
TASK_ADDRESS = new ArrayBlockingQueue<>(bufferPool.getCapacity());
TASK_MARKER = new ArrayBlockingQueue<>(bufferPool.getCapacity());
BUFFER_POOL = bufferPool;
APPENDER = chronicleQueue.acquireAppender();
}