而是等待,"放弃"任务,将其返回到队列并将线程释放回线程池

时间:2016-02-03 11:03:01

标签: java multithreading locking threadpool executorservice

我想知道是否有办法处理某些ExecutorService中的任务,而不是阻塞工作线程(由于监视器锁定),它将放弃该任务,并将其返回给队列供以后处理。 这也将释放工作线程以执行其他任务。

动机是某些任务可能需要使用占用大量时间的共享资源,而其他任务则不需要它:

if(AllConditionsHaveMet()){
    KeepRunning();
}
else{
    // instead of locking, put it back and take next task (unless the queue is empty)
    synchronized (_locker)
    {
        TakeALotOfTime();
    }
}

2 个答案:

答案 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);
        }
    }
    

随意发表评论。