有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将等待,“放弃”一个任务,将其返回队列,并将线程释放回线程池

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

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

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

共 (2) 个答案

  1. # 1 楼答案

    所以最终,我采用了一种稍微不同的方法
    我没有让线程主动等待,而是将@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);
          }
      }
      

    请随意评论

  2. # 2 楼答案

    所以你有快任务和慢任务;后者应推迟自己(重新提交相同的服务)。(是的,您应该使用ReentrantLock.tryLock()

    使用executorservice上的优先级队列对缓慢的任务进行排序并移开。 您的任务将是可比较的,初始权重为0。慢任务1

    在这里,延迟的次数是一个因素,如果优先级队列不能确保只有在没有更多快速任务的情况下才能运行慢速任务,那么就可以避免饥饿