heeboir
heeboir

Reputation: 739

Prioritizing tasks for execution in a Java ThreadPoolExecutor

Is there a way to prioritize tasks for execution in a Java ThreadPoolExecutor? The problem that I am facing is that there are threads that need to be executed in order when based on an identical specified execution identifier.

They are all submitted to the same ThreadPoolExecutor but due to processing delays it is possible that task A2 completes before task A1 (which has the same execution identifier). They should follow the same ordering as when they enter while not blocking other tasks (with different execution identifiers) from executing (e.g. B1, B2, C1, etc.).

Is there a common pattern for handling a problem like that? For example, tasks A1, B1, B2, A2, C1 enter the pool for processing. They should be processed in the following manner:

A1

B1

B2 (if B1 has completed, otherwise wait until B1 completes while A2 or C1 take turn)

A2 (if A1 has completed, otherwise wait until A1 completes while B2, if not started already, or C1 take turn)

C1

Upvotes: 0

Views: 404

Answers (2)

Kajal Sinha
Kajal Sinha

Reputation: 1565

Make use of java.util.concurrent package instead of thread pool. It had Future tasks which can help you in ordering and queuing your actionable items.

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html

Update 1:

You can use the following sample. Please correct me if I am wrong, one thing which I see missing in Java FutureTasks is chaining. In .NET you can Chain multiple tasks and define dependencies (e.g. ContinueWith and TaskContinuationOptions, Wait(task) etc..) outside the body of individual task's Call method.

package sample;
import java.util.concurrent.*;

public class FutureTaskTest {

    public static void main(String[] args)
    {

         ExecutorService executor = Executors.newFixedThreadPool(3);

         final FutureTask<String> a1 = new FutureTask<String>(
                    new Callable<String>()
                    {
                        public String call()
                        {
                           System.out.println("a1 finished.");
                           return "Success";

                        }
                    });

         FutureTask<String> a2 = new FutureTask<String>(
                    new Callable<String>()
                    {
                        public String call()
                        {
                           try {
                            a1.get();
                        } catch (InterruptedException | ExecutionException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }//wait for a1 to finish.
                           System.out.println("a2 finished.");
                           return "Success";
                        }
                    });
         final FutureTask<String> b1 = new FutureTask<String>(
                    new Callable<String>()
                    {
                        public String call()
                        {
                            System.out.println("b1 finished.");
                            return "Success";
                        }
                    });
         FutureTask<String> b2 = new FutureTask<String>(
                    new Callable<String>()
                    {
                        public String call()
                        {
                            try {
                                b1.get();
                            } catch (InterruptedException | ExecutionException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }//wait for b1 to finish.
                           System.out.println("b2 finished.");
                            return "Success";
                        }
                    });
         FutureTask<String> c1 = new FutureTask<String>(
                    new Callable<String>()
                    {
                        public String call()
                        {
                            System.out.println("c1 finished.");
                            return "Success";
                        }
                    });


         executor.execute(a1);
         executor.execute(a2);
         executor.execute(b1);
         executor.execute(b2);
         executor.execute(c1);
         }

}

And here is the output.

a1 finished.
b1 finished.
b2 finished.
c1 finished.
a2 finished.

Regards Kajal

Upvotes: 0

assylias
assylias

Reputation: 328598

You can create a ThreadPoolExecutor with a PriorityBlockingQueue.

Upvotes: 1

Related Questions