3

I'm creating a reader application. The reader identifies based on the parameters which file to read, does some processing and returns the result to the caller.

I am trying to make this multi-threaded, so that multiple requests can be processed. I thought it was simple but later realized it has some complexity. Even though i create threads using executor service, I still need to return the results back to the caller. So this means waiting for the thread to execute.

Only way i can think of is write to some common location or db and let the caller pick the result from there. Is there any approach possible?

7
  • 1
    When submitting to an executor service you'll get a future, why don't you wait for its completion? Commented Sep 30, 2011 at 11:14
  • Thanks Thomas, but it means the process need to wait for the result from the Future. Commented Sep 30, 2011 at 11:16
  • So you have to multithread the requests from the processes. From where do you get them? RPC/RMI/Sockets? Would be great if you can show some code ;) Commented Sep 30, 2011 at 11:20
  • 1
    what is the expected interaction between the "caller" and the worker threads? you seem to be indicating that the caller is asynchronous, i.e. it submits a request and polls for results later? Commented Sep 30, 2011 at 11:41
  • The calls would be across sockets. Haven't written the code yet. Still in the process of designing :) Commented Sep 30, 2011 at 11:50

2 Answers 2

3

Maybe an ExecutorCompletionService can help you. The submitted tasks are placed on a queue when completed. You can use the methods take or poll depending on if you want to wait or not for a task to be available on the completion queue.

ExecutorCompletionService javadoc

Sign up to request clarification or add additional context in comments.

Comments

1

Use an ExecutorService with a thread pool of size > 1, post custom FutureTask derivatives which override the done() method to signal completion of the task to the UI:

public class MyTask extends FutureTask<MyModel> {
  private final MyUI ui;

  public MyTask(MyUI toUpdateWhenDone, Callable<MyModel> taskToRun) {
    super(taskToRun);
    ui=toUpdateWhenDone;
  }
  @Override
  protected void done() {
    try {
      // retrieve computed result
      final MyModel computed=get();
      // trigger an UI update with the new model
      java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
           ui.setModel(computed); // set the new UI model
        }
      });
    }
    catch(InterruptedException canceled) {
       // task was canceled ... handle this case here
    }
    catch(TimeoutException timeout) {
      // task timed out (if there are any such constraints). 
      // will not happen if there are no constraints on when the task must complete
    }
    catch(ExecutionException error) { 
      // handle exceptions thrown during computation of the MyModel object...
      // happens if the callable passed during construction of the task throws an 
      // exception when it's call() method is invoked.
    }
  }
}

EDIT: For more complex tasks which need to signal status updates, it may be a good idea to create custom SwingWorker derivatives in this manner and post those on the ExecutorService. (You should for the time being not attempt to run multiple SwingWorkers concurrently as the current SwingWorker implementation effectively does not permit it.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.