如何在 BlockingQueue java 中优雅地等待作业任务完成
How to gracefully wait to job task finish in BlockingQueue java
我正在使用 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;
}
}
}
如有任何改进建议,我们将不胜感激!
if (mBlockingQueue.isEmpty()) {
mQueueState = PollingQueueState.WAITING;
} else {
mQueueState = PollingQueueState.FETCHING;
}
if (mQueueState == PollingQueueState.FETCHING)
删除这些行、break;
和匹配的右大括号。
您不需要测试队列是否为空,您只需 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;
}
我正在使用 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;
}
}
}
如有任何改进建议,我们将不胜感激!
if (mBlockingQueue.isEmpty()) {
mQueueState = PollingQueueState.WAITING;
} else {
mQueueState = PollingQueueState.FETCHING;
}
if (mQueueState == PollingQueueState.FETCHING)
删除这些行、break;
和匹配的右大括号。
您不需要测试队列是否为空,您只需 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;
}