我想知道是否有办法处理某些ExecutorService
中的任务,而不是阻塞工作线程(由于监视器锁定),它将放弃该任务,并将其返回给队列供以后处理。
这也将释放工作线程以执行其他任务。
动机是某些任务可能需要使用占用大量时间的共享资源,而其他任务则不需要它:
if(AllConditionsHaveMet()){
KeepRunning();
}
else{
// instead of locking, put it back and take next task (unless the queue is empty)
synchronized (_locker)
{
TakeALotOfTime();
}
}
答案 0 :(得分:0)
所以你有快速的任务和缓慢的任务;后者应推迟自己(重新提交给同一执行者服务)。 (是的,你应该使用ReentrantLock.tryLock())。
在executorservice上使用优先级队列来排序和移除慢速任务。 你的任务将实现Comparable,初始权重为0.慢任务1.
推迟的次数将是这里的一个因素,如果优先级队列不能确保只有在没有更快的任务时才运行慢速任务,则可以避免饥饿。
答案 1 :(得分:0)
所以最终,我的方法略有不同
我没有让线程主动等待,而是将@Fildor建议和CompletableFuture<T>
混合在一起作为等待部分。
要明白以下几行,请记住:
1. Worker
类实现IProcessingWorker
,扩展Callable<Void>
2.真正的解决方案是将监视器锁定作为TakeALotOfTimeAsync ()
实现的一部分
3.真正的解决方案还会计算尝试次数,如果超过则暂停。
看起来像这样:
创建工人
_executer = Executors.newFixedThreadPool(workersCount, threadFactory);
...
IProcessingWorker worker = _processingWorkerFactory.Create(payload);
worker.setExecuterService(_executer);
_executer.submit(worker);
工作人员
ExecuterService _threadPool;
@Override
public void setExecuterService(ExecutorService threadPool)
{
_threadPool = threadPool;
}
@Override
public Void call() throws Exception
{
if(AllConditionsHaveMet())
{
KeepRunning();
}
else
{
CompletableFuture<Void> future = TakeALotOfTimeAsync();
future.handleAsync((res, ex) ->
{
if(ex != null) { // handle error }
try
{
call();
}
catch(Exception e)
{
// handle error
}
return res;
}, _threadPool);
}
}
随意发表评论。