Question

I have the following Foo class that uses FooProcessor class. So what i want to do is, while running cp1 instance process method, in parallel I want to run cp2.process().

public class Foo {

    public static void main(String [] args){

        FooProcessor cp1 = new FooProcessor();
        FooProcessor cp2 = new FooProcessor();

        cp1.process();
        // in parallel process cp2.process();
    }

}

public class FooProcessor {
    public void process(){
        System.out.println("Processing..");
    }
}

However, i want cp1 sequentially, so i want it to run and complete, if cp2 doesnt complete or fails it is fine. If it doenst fail i want to join the results. It is not returning anything in this sample but I want to return result.

For this purpose, should is use TaskExecutor? or Thread?

I want only cp2 to run in parallel to cp1. or if i add more lets say cp3, i want that to run in parallel as well to cp1.

Was it helpful?

Solution

The way I would implement it, in summary :

  • run your different processes via an ExecutorService, for example ExecutorService executor = Executors.newFixedThreadPool(nThreads);
  • store the Futures of all your tasks in a List (returned by ExecutorService#submit)
  • wait for future1.get() to complete, where future1 is the future linked to cp1
  • once get returns (cp1 has finished) cancel all the other futures, (or shutdownNow the executor service if you don't need the executor any longer)
  • for that cancellation process to work, your cp2, cp3 etc need to implement an interruption policy that makes them stop what they are doing asap.

OTHER TIPS

Thread would be a good choice...Something like a method that accepts a new threads and start them...

According to https://stackoverflow.com/a/2269177/454167,

You can use something like a AsyncTaskExecutor[1], which returns a Future object. You can then wait on the Future to know if cp2 returns success.

[1] http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/core/task/AsyncTaskExecutor.html#submit%28java.lang.Runnable%29

You can of course use plain and simple Threads
If you know you need to add more methods to the processor class, and for a given instance of it to keep execution order - let's say you first run method foo, and then run method bar, and you want them to run asynchronously, but keep execution order (first foo, then bar), I would consider to use Active Object pattern.
I recommend also using this approach because for the user of the processor class it will hide implementation details.
In addition, consider providing a decorator/wrapper that will provide this async ability to your objects - this way you will be able to control which object is run asynchronously and which isn't, and you will not have to "pollute" your Processor class with code needed for asynchronous invocation.
An example of usage in this case will be -

AsyncProcessor ap  = new AsyncProcessor(p1);
ap.process();  //executed asynchronously
Proccessor p2 = new Processor();
p2.process(); //executed synchronously



Another apporach is to use as you mentioned, an executor - This can be achieved by implementing a thread pool and pushing "execution units to it".
An execution unit will contain the target object (cp1, cp2, ...) and the method to execute (currently - only process)
The threads will take "an execution unit" from the queue and run them.
The implementation is similar to active object, but the "interface" for the user is different as it uses a "TaskExecutor" class to provide it "execution units"

If you're writing your own standalone application, using threads might be the easiest way forward. If you're in a Java EE environment, you should not create your own Thread objects, but use some other mechanism (such as sending messages and have message listeners process the signals you send). This is to have the Java EE container control resource utilization such as thread pools.

Example of using Threads:

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
         executeSomeCodeInP1();
    }
});

Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
         executeSomeCodeInP2();
    }
});

t1.start();
t2.start();

// if you want to wait for both threads to finish before moving on, 
// "join" the current thread
t1.join();
t2.join();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top