Java Interview Reference Guide – Concurrent Framework

The Java Concurrent framework provide a powerful, extensible framework of high-performance threading utilities such as thread pools, Executors, synchronize, concurrent collection, locks, atomic variables and Fork/Join.

Concurrent framework consists below packages:

Java.util.concurrent: It is main package, which provides common libraries such as concurrent collection (ConcurrentHashMap.), ForkJoin, Executors, and Semaphore etc. to build concurrent application.

Java.util.concurrent.atomic: This subclass provide thread safe variable without synchronized key. It uses CAS (compare-and-set) instruction support to provide thread safe.

Java.util.concurrent.locks: This subclass contains low-level utility types for locking and waiting for conditions without using synchronization and monitors. Java.util.concurrent.locks.ReentrantLock implements Lock interface is more efficient over traditional synchronized based monitor lock mechanisms.

ThreadPoolClassDiagram

 

 

The Executor framework also provides implementation of the java.util.concurrent.Executor interface, such as Executors.newFixedThreadPool (int n), which will create n worker threads.

ThreadPoolExecutor is one of the implementation of ExecutorService in java.util.concurrent packages.

Executors:

Executor’s class is an utility/factory class to create various Executor implementations such as ExecutorService, ScheduledExecutorService. It can also use to create ThreadFactory and Clalable class.

We can basically create three type of ExecutorService as below

  • ExecutorService executorService1 = Executors.newSingleThreadExecutor();
  • ExecutorService executorService2 = Executors.newFixedThreadPool (8);
  • ExecutorService executorService3 = Executors.newScheduledThreadPool (8);
  • ExecutorService executorService4 = Executors.newCachedThreadPool (8);

SingleThreadExecutor:

It creates Executor (ExecutorService) that spawns single thread to execute tasks in sequential manner. If single thread terminates due to failure, new thread will create and take task to execute and complete the process.

FixedThreadPool:

It creates pool of thread, which reused to process the tasks. At any time at most n Thread will be processing tasks. If new tasks are submitted then they will wait in the queue until a thread is available.

ScheduledThreadPool:

Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.

CachedThreadPool

Create a thread pool that creates new thread based on demand and reuse previously constructed if they are available.

Difference between FixedThreadPool and CachedThreadPool

The main difference is that FixedThreadPool will keep all the threads running until they are explicitly terminated but CachedThreadPool Threads that have not been used for sixty seconds are terminated and removed from the cache and release the resources. Therefore CachedThreadPool improve the performance for the programs that have many short-lived asynchronous tasks but if you have a long running tasks then FixedThreadPool will be preferable.

Execute using Runnable interface


import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

class TaskRunnable implements Runnable {

private String taskName;

public TaskRunnable(String taskName) {

this.taskName = taskName;

}

@Override

public void run() {

System.out.println("Executing task:" + taskName + "on Thread: "

+ Thread.currentThread().getName());

}

}

public class ExecutorSample {

public static void main(String[] args) {

// Create objects of Runnable

TaskRunnable task1 = new TaskRunnable("task1");

TaskRunnable task2 = new TaskRunnable("task2");

TaskRunnable task3 = new TaskRunnable("task3");

ExecutorService executorPoo = Executors.newFixedThreadPool(2);

executorPoo.execute(task1);

executorPoo.execute(task2);

executorPoo.execute(task3);

executorPoo.shutdown();

}

}

Output:

Executing task:task2on Thread: pool-1-thread-2

Executing task: task1 on Thread: pool-1-thread-1

Executing task: task3 on Thread: pool-1-thread-2

Execute using Callable interface:

Runnable interface neither return value nor track checked exception if occurred. Callable overcome these problem by using method call () which is similar to run() method in runnable but it throw exception and return value.


class CallableTask implements Callable<Integer> {

@Override

public Integer call() {

return 1;

}

}

public class CallableSample {

public static void main(String[] args) {

FutureTask<Integer> task = new FutureTask<Integer>(new CallableTask());

ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.submit(task);

try {

System.out.println("Return value: " + task.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

executorService.shutdown();

}

Output

Return value: 1

FutureTask

FutureTask is an implementation of Future interface, which retrieve the result of computation of Callable class. The get method retrieve result once computation get completed and till that time it will block the computation.

ExecutorService Usage

We can execute task using below methods:

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(…)
  • invokeAll(…)

public void execute(Runnable command)

This method executes run method of Runnable object asynchronously. Since run method of runnable object doesn’t return result hence we cannot able to obtain the result of the executable runnable.

Below is the code how to use execute method on ExecutorService:


ExecutorService executorSer = Executors.newSingleThreadExecutor ();

executorSer.execute (new Runnable () {

public void run() {

System.out.println("Executing runnable process ");

}

});

executorService.shutdown ();

Future<?> submit(Runnable task)

It also submit runnable task to execute but it return a Future task. This Future’s get method will return null after successful completion. This Future object can be used to check if the Runnable as finished executing.

Here is a ExecutorService submit () example:


Future future = executorService.submit(new Runnable() {

public void run() {

System.out.println("Executing runnable process ");

}

});

future.get();  //returns null if the task has finished correctly.

<T> Future<T> submit (Callable<T> task);

Submit a Callable class, which return Future-having result of process completion. Future’s get method will return the task’s result upon successful completion.


Future futureResult=executorService.submit(new Callable(){

Public Object call() throws Exception{

System.out.println(“Executing callable process”);

return “Callable process completed”;

}

});

System.out.println("future.get() = " + future.get());

If you would like to immediately block the waiting for a task, you can use as below

result = executorService.submit(new Callable(){

Public Object call() throws Exception{

System.out.println(“Executing callable process”);

return “Callable process completed”;

}

}).get();

<T> T invokeAny (Collection<? extends Callable<T>> tasks)

It executes collection of callable task and return any one, which completed successfully and rest of the tasks that have not completed are cancelled. You have no guarantee about which of the Callable’s results you get. Just one of the ones that finish. If one of the tasks complete (or throws an exception), the rest of the Callable’s are cancelled.

Below is the sample code for invokeAny


ExecutorService execSer = Executors.newSingleThreadExecutor ();

Collection<Callable<String>> listCollable = new ArrayList<Callable<String>>();

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return "Result Task 1";

}

});

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return " Result Task 2";

}

});

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return " Result Task 3";

}

});

String taskResult = execSer. InvokeAny(listCollable);//Result could be either “Result Task 1” or “Result Task 1” or “Result Task 3”

execSer.shutdown();

<T> List<Future<T>> invokeAll (Collection<? extends Callable<T>> tasks)

This method returns a list of all Future of completed task with their status. isDone() method of Future object is true for all Future in return Future list. The results of this method are undefined if the given collection is modified while this operation is in progress.

Below is the sample code for invoke All


ExecutorService execSer = Executors.newSingleThreadExecutor ();

Collection<Callable<String>> listCollable = new ArrayList<Callable<String>>();

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return "Result Task 1";

}

});

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return " Result Task 2";

}

});

listCollable.add(new Callable<String>() {

public String call() throws Exception {

return " Result Task 3";

}

});

List<Future<String>> futures = execSer.invokeAll(listCollable);

for(Future<String> future : futures){

System.out.println("Result = " + future.get());

}

execSer.shutdown();

void shutdown();

After completing the task shutdown method of ExecutorService complete process of previously submitted task and doesn’t accept new task. The shutdown method doesn’t immediately shutdown tasks but wait to complete all tasks before terminating threads

The shutdownNow () method of Executor Service will attempts to stop all executing tasks right away, and skips all submitted but non-processed tasks.

References:
http://docs.oracle.com
http://stackoverflow.com/
http://en.wikipedia.org/
Effective Java™

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s