一旦我得到未来的结果,什么是重新提交可调用的最佳方法?

时间:2011-07-11 23:33:03

标签: java concurrency

有更好的方法吗?我宁愿使用j.u.c中的现有框架而不是自己编译....

请查看“运行”方法。

我需要在从Future获得结果后立即重新提交Callable。 我正在使用这个单独的Runnable Thread,就是这样做,如下所示。

虽然这应该编译,但它显然不是一段代码......

public class ResubmitOnCompletion implements Runnable {

    private CompletionService<DeviceData> completionService;

    private ConcurrentHashMap<String, Device> devices;

    public void run() {

      //-- keep resubmitting the callable.
      while(true){


        try {
          //-- Get the returned data from completed job
          Future<DeviceData> f=null;
          DeviceData dd=null;

          f = completionService.take();

          //-- Get the completed job's data 
          dd=f.get();

          //-- now resubmit the job if device still is part of the active device collection
          completionService.submit((Callable<DeviceData>) devices.get(dd.getDeviceId()));
      }
      catch (CancellationException e) {
        e.printStackTrace();
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      } catch (ExecutionException e) {
        e.printStackTrace();
      }         
    }   
  }


    //-- Device Data
    private class DeviceData {
      /**
       * Unique Device Identifier
       */
      private final String deviceId;

      /**
       * Holds all numeric data of the device.
       * Key=Variable id of the parameter
       * Value=Numeric value of the parameter
       */
      private final ConcurrentHashMap<String, BigDecimal> numericData;



      private DeviceData(String deviceId,
          ConcurrentHashMap<String, BigDecimal> numericData) {
        super();
        this.deviceId = deviceId;
        this.numericData = numericData;
      }


      /**
       * @return the deviceId
       */
      public String getDeviceId() {
        return deviceId;
      }

      /**
       * @return the numericData
       */
      public ConcurrentHashMap<String, BigDecimal> getNumericData() {
        return numericData;
      }
    }   

    //-- Device
    private class Device {
      public DeviceData call() throws Exception {
        return new DeviceData("",new ConcurrentHashMap<String, BigDecimal>());
      }

    }
}

3 个答案:

答案 0 :(得分:2)

为什么不让工作本身检查最后的状态,并在必要时重新提交。只要您的执行程序具有无限制的队列,这将起作用。

答案 1 :(得分:2)

您可以简单地提交Runnable并在运行中重新提交

ExecutorService e = Executors.newFixedThreadPool(1);

private void submitWork(){
   e.submit(new Runnable(){
       public void run(){
          ///do work with devices and get its data            
          e.submit(this);
       }
   });
}

我不确定为什么这不起作用。

答案 2 :(得分:1)

我认为ExecutorService / CompletionService并不是您想要的。如果你想让这个工作继续下去,那么你真的有一个产生BlockingQueue结果的工人线程。

如果您需要限制在任何特定时间运行的线程数量,这是一个不同的问题,但目前您只需存储生产者线程用于将结果放入的ConcurrentMap<String, BlockingQueue<DeviceData>>并且消费者读取结果来自。