开发者

What is best way to resubmit a callable as soon as I get a result from the future?

开发者 https://www.devze.com 2023-03-19 18:58 出处:网络
Is there a better way to do this?I would rather use an existing framework from j.u.c instead of rolling my own....

Is there a better way to do this? I would rather use an existing framework from j.u.c instead of rolling my own....

Please look at the "run" method.

I need to resubmit the Callable as soon as a result is obtained from the Future. I'm using this separate Runnable Thread, just to do exactly this, as shown below.

Though this should compile, its obviously not a working piece of code..

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>());
      }

    }
}


You can simply submit the Runnable and within the run re submit itself

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

I am unsure why this would not work.


Why don't you make the job itself check the status at the end and resubmit itself if necessary. this will work as long as your executor has an unbounded queue.


I don't think an ExecutorService/CompletionService is what you want really. If you want the job to continue, then you are really have a worker thread that is producing a BlockingQueue of results.

If you need to restrict the number of threads running at any particular time that is a different concern, but for the moment you can simply store a ConcurrentMap<String, BlockingQueue<DeviceData>> that the producer thread uses to put results into and the consumers reads results from.

0

精彩评论

暂无评论...
验证码 换一张
取 消