Java Executor Framework Example

Hello Readers,

This post will show an example of writing multi-threaded program using Executor framework introduced in Java 1.5.

Before making  your program multi-threaded, you should define task boundaries. If you are doing n independent tasks sequentially, then using multiple threads can go a long way in speeding up processing by utilizing CPU power.

Executor framework takes care of thread life cycle management and you can focus on the tasks to be done. It is based on Producer-Consumer pattern. Activities that submit tasks are producers and activities that perform tasks are consumers. Producer and Consumer are decoupled from each other by using the BlockingQueue interface. A BlockingQueue holds all tasks (work items). Producer keeps adding tasks to BlockingQueue and Consumers keep consuming them from BlockingQueue. So you don’t have to manage conditions when either Producer or Consumer is working at a faster rate. There are many implementations of BlockingQueue available to use based on your requirements.

Let’s see some action. Consider you want to read data from 2 files and these are independent operations. So instead of reading them sequentially, you could have 2 threads read them in parallel. Let even.txt contain even numbers between 0 and 99 and odd.txt contain odd numbers.

First, we write a ThreadWorker that will do the task of reading a file.

package com.badalchowdhary.threads;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * ThreadWorker represents the tasks to be done. It consumes work items from
 * Blocking Queue and invokes the run method on each task submitted by producer.
 *
 * @author badal
 *
 */
public class ThreadWorker implements Runnable {

public ThreadWorker(File file) {
 super();
 this.file = file;
 }

public void run() {
 try {
 BufferedReader br = new BufferedReader(new FileReader(getFile()));
 String line = null;
 while ((line = br.readLine()) != null) {
 System.out.println(getFile().getName() + " - " + line);
 }
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }

File file;

public File getFile() {
 return file;
 }

public void setFile(File file) {
 this.file = file;
 }

}

Next and last, we will write a program to:
1. Instantiate a BlockingQueue to hold work items.

2. Instantiate an Executor to specify number of threads, timeout and BlockingQueue to be used.

3. Create 2 tasks.

4. Submit tasks to Executor created in Step 2.

5. Shutdown the executor. It basically says, run the submitted the tasks and no more tasks will be submitted.

6. Wait for executor to finish all tasks before continuing ahead.

package com.badalchowdhary.threads;

import java.io.File;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadExample {

public static void main(String[] args) {
 // Create a blocking queue to hold work items (runnables). Decouples
 // producers and consumers.
 BlockingQueue workQueue = new LinkedBlockingQueue();

// Create a thread pool executor with core size and maximum size as 2,
 // specify a time out and pass the blocking queue
 ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, Long.MAX_VALUE, TimeUnit.SECONDS, workQueue);

ThreadWorker worker1 = new ThreadWorker(new File("even.txt"));
 ThreadWorker worker2 = new ThreadWorker(new File("odd.txt"));

// Submit runnable to thread pool executor
 executor.submit(worker1);
 executor.submit(worker2);

// Gracefully shutdown thread pool executor. All submitted tasks will
 // run to completion, no new tasks will be accepted.
 executor.shutdown();

// Wait for all submitted tasks to complete. Handle InterruptedException
 // if thread pool executor is interrupted.
 try {
 executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
 } catch (InterruptedException e) {
 System.out.println("ThreadPoolExecutor was interrupted. Do appropriate handling.");
 e.printStackTrace();
 }

}

}

The output on console will toggle as both even.txt and odd.txt are being processed by 2 processors simultaneously. Below is a snapshot:


 even.txt - 0
 even.txt - 2
 odd.txt - 1
 odd.txt - 3
 odd.txt - 5
 odd.txt - 7
 odd.txt - 9
 odd.txt - 11

Hope this post was useful. Always looking for feedback from readers.

Your’s Truly

Advertisements

About Badal Chowdhary

I am a Software Engineer by profession. I have done SCJP and SCWCD certifications. Like working on cutting edge technologies and frameworks. Driven by challenges and fascinated by technology. I love playing and watching sports: Cricket, Ping Pong, Tennis, Badminton, Racket Ball and Gym.
This entry was posted in Core Java and tagged , , , , , . Bookmark the permalink.

8 Responses to Java Executor Framework Example

  1. Anonymous says:

    Very detailed – Sudheer

  2. Atul Kushwaha says:

    Nice Stuff.

    But what is the Added Advantage of using Executor Framework over using Threads w\out Executor Framework.
    One added feature is , automatic handling of Thread Life cycle.

    • Thanks Atul! Other advantages are out of the box support for thread pools, scheduling of threads. It also provides a cleaner way to block using Blocking queue mechanisms. Since the API takes care of infrastructure, you can focus on solving your problem.

  3. Pankaj Vaidya says:

    Hi Badal,
    Wonderful explanation in small simple example. Now, this concept is clear to me

  4. anil kumar says:

    good effort

  5. Anonymous says:

    Hi Badal, I want to develop some code similar to producer and consumer and blocking queue , but i want it like producer will put the available file name to database (queue) and consumer should pick it up from db. can you please provide an example

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