Google

Jul 5, 2014

Java Executor service to run concurrently and sequentially with strategy design pattern - part 2

Firstly, write a default executor by extending AbstractExecutorService class and implementing the relevant methods like shutdown(), execute(Runnable command), etc.

Part 1: Running concurrent threads
Part 2: Running sequential threads
Part 3: Creating a strategy class using the strategy design pattern to be able switch between running concurrently and sequentially. 


package com.writtentest13;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class DefaultThreadExecutor extends AbstractExecutorService {

 private boolean flagShutdown = false; // shut down flag
 private AtomicLong executingTasks = new AtomicLong(); // atomic counter
 private Object terminationMutex = new Object();

 @Override
 public void shutdown() {
  this.flagShutdown = true;
 }

 @Override
 public List<Runnable> shutdownNow() {
  shutdown();
  // best practice to favor empty collection over a null.
  return Collections.emptyList();
 }

 @Override
 public boolean isShutdown() {
  return this.flagShutdown;
 }

 @Override
 public boolean isTerminated() {
  return (isShutdown() && (this.executingTasks.get() == 0));
 }

 @Override
 public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
  if (isTerminated()) {
   return true;
  }

  // favor TimeUnit class to Thread.sleep
  synchronized (this.terminationMutex) {
   this.terminationMutex.wait(unit.toMillis(timeout)); // waiting to be
                                                       // notified
  }
  return isTerminated();
 }

 @Override
 public void execute(Runnable command) {
  if (isShutdown()) {
      throw new IllegalStateException("The executor is already shutdown.");
  }

  this.executingTasks.incrementAndGet();
        
  System.out.println("Starting to execute task ..." );
  
  command.run(); // run it on a thread
  
  System.out.println("Finished executing task ..." );

  long remaining = this.executingTasks.decrementAndGet();
  
  if (isShutdown() && (remaining == 0)) {
   synchronized (this.terminationMutex) {
       terminationMutex.notifyAll(); // notify waiting threads
   }
  }

 }

}



Use the above method in the main class shown below to run sequentially in the main thread itself.

package com.writtentest13;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 
 * Tasks are executed sequentially on the current thread
 *
 */
public class ThreadExecutorMainSeq {

 private ExecutorService currentThreadExecutor;

 public static void main(String[] args) {
  ThreadExecutorMainSeq main = new ThreadExecutorMainSeq();
  
  //sequential executor
  main.currentThreadExecutor = new DefaultThreadExecutor();
  List<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
  
  //create dummy tasks
  for (int i = 1; i <= 5; i++) {
   tasks.add(main.createTask(i));
  }

  //submit the tasks to the currentThreadExecutor
  try {
   main.currentThreadExecutor.invokeAll(tasks);
   while(main.currentThreadExecutor.awaitTermination(2, TimeUnit.SECONDS)){
    
   }
   
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  
  System.out.println("Completed .........");

 }

 private Callable<Boolean> createTask(final int i) {

  Callable<Boolean> task = new Callable<Boolean>() {

   @Override
   public Boolean call() throws Exception {
    System.out.println("Performing task " + i + " on thread - " + Thread.currentThread().getName());
    return true;
   }

  };

  return task;

 }
}



The output will be

Starting to execute task ...
Performing task 1 on thread - main
Finished executing task ...
Starting to execute task ...
Performing task 2 on thread - main
Finished executing task ...
Starting to execute task ...
Performing task 3 on thread - main
Finished executing task ...
Starting to execute task ...
Performing task 4 on thread - main
Finished executing task ...
Starting to execute task ...
Performing task 5 on thread - main
Finished executing task ...
Completed .........

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home