Thursday, January 27, 2011

Using Java Executor Framework...

Java Executor Framework provides a solution using a thread pool to the following problems of using threads directly:

  • Creating a new thread causes some performance overhead.
  • Too many threads can lead to reduced performance, as the CPU needs to switch between these threads.
  • You cannot easily control the number of threads, therefore you may run into out of memory errors due to too many threads.
Here's a code snippet on how you can use it:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestExecutor {
   
    private static final int NTHREDS = 10;

    /**
     * @param args
     */
    public static void main(String[] args) {

        long l=System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
        for (int i = 0; i < 10000; i++) {
            Runnable worker = new Test(i);
            executor.execute(worker);
        }
        // This will make the executor accept no new threads
        // and finish all existing threads in the queue
        executor.shutdown();
        // Wait until all threads are finish
        while (!executor.isTerminated()) {

        }
        System.out.println("Total time: "+ (System.currentTimeMillis()-l));
    }
public class Test implements Runnable {

    private int id;
   
    public Test(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        int sum=id;
        for(int j=0; j<10000000;j++)
            sum += j;
        System.out.println("My sum = "+sum);
    }
}

You may note that I have used a thread pool with ten threads, you can change the size of the pool according to your need.

You may wonder what actually applying concurrency does to your application's performance. Here's a comparison of CPU usage without and with using threads.



My application without using threads!

Application is running in the time gap

of 40 - 0 seconds in the CPU history

graph. You may note that CPU

utilization is 30% & 100%. i.e. not

effectively utilized.







My application using threads!

Application is running in the time gap

of 25 - 0 seconds in the CPU history

graph. You may note that CPU

utilization is 100% & 100%. Thus the

both CPUs are effectively utilized.





There is another way that you can get the advantage of Java Executor Framework, I will elaborate on that in my next post! :)

Happy Threading!! :D

No comments: