我正在使用BlockingQueue和ExecutorService编写一个作业队列。它基本上等待队列中的新数据,如果有任何数据放入队列,executorService将从队列中获取数据。但问题是我使用的循环循环等待队列拥有数据,因此CPU使用率非常高。 我是新手使用这个api。不知道如何改善这一点。
ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
BlockingQueue<T> mBlockingQueue = new ArrayBlockingQueue();
public void handleRequests() {
Future<T> future = mExecutorService.submit(new WorkerHandler(mBlockingQueue, mQueueState));
try {
value = future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if (mListener != null && returnedValue != null) {
mListener.onNewItemDequeued(value);
}
}
}
private static class WorkerHandler<T> implements Callable<T> {
private final BlockingQueue<T> mBlockingQueue;
private PollingQueueState mQueueState;
PollingRequestHandler(BlockingQueue<T> blockingQueue, PollingQueueState state) {
mBlockingQueue = blockingQueue;
mQueueState = state;
}
@Override
public T call() throws Exception {
T value = null;
while (true) { // problem is here, this loop takes full cpu usage if queue is empty
if (mBlockingQueue.isEmpty()) {
mQueueState = PollingQueueState.WAITING;
} else {
mQueueState = PollingQueueState.FETCHING;
}
if (mQueueState == PollingQueueState.FETCHING) {
try {
value = mBlockingQueue.take();
break;
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage(), e);
break;
}
}
}
非常感谢任何有关如何改善这一点的建议!
答案 0 :(得分:1)
if (mBlockingQueue.isEmpty()) {
mQueueState = PollingQueueState.WAITING;
} else {
mQueueState = PollingQueueState.FETCHING;
}
if (mQueueState == PollingQueueState.FETCHING)
删除这些行,break;
和匹配的右括号。
答案 1 :(得分:1)
您不需要测试队列为空,只需要take()
,因此线程会阻塞,直到数据可用。
当一个元素被放入队列时,线程唤醒一个值被设置。
如果您不需要取消刚才需要的任务:
@Override
public T call() throws Exception {
T value = mBlockingQueue.take();
return value;
}
如果您想取消任务:
@Override
public T call() throws Exception {
T value = null;
while (value==null) {
try {
value = mBlockingQueue.poll(50L,TimeUnit.MILLISECONDS);
break;
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage(), e);
break;
}
}
return value;
}