Multicore programming and Threading in Java

Java is one language that I believe really made multi-threading easy! really easy!

A lot of other languages followed in the footsteps of Java to make similar threading models and creating the necessary abstraction making application programmer's life really simple.

In the multi-core age it's critical to have your application/program full advantage of all the horse power the underlying system has to offer therefore knowing multi-threading framework is very critical.

The Concurrent package in Java contains pretty much everything you will ever need to multi-threaded programming in Java. So let's get our hands a bit dirty with some real stuff.

Threads:
You can instantiate a new thread in Java using the the Thread class or by implementing a Runnable interface. Threads can be instantiated busing anonymous inner types (inline implementation):

Thread th = new Thread ("optionalName") {

@Override
public void run(){
//    Whatever you want to do
}

}

//now starting the thread
th.start();

Using Runnable:
class Test implements Runnable {

//or you could say extends Thread, either one will work; best practice is to implement runnable
public void run(){
//do work here
}

}

Thread th1=new Thread(new Test());
th1.start();

Passing parameters to thread:
Well pretty much any anonymous inner type thread will be able to access variables declared elsewhere in class/function till they are visible to it. Java will ask you to make a variable final if it is used in a thread, because final prevents you from re initializing it.

As I have mentioned above that you can implement Runnable interface to make your class "threadable" i.e. run your object as a thread. You should be easily able to implement a parameterized constructor and pass that parameter while instantiating the thread. One other and highly discouraged way is using final object i.e. an object that has been finalized.
The reason behind discouraging final is because final doesn't ensure it's thread safe, it just ensures that it can't be re-instantiated, but as we know most complex objects and data-structure objects are just containers of a lot of information therefore just marking an object final doesn't ensure anything.

Thread Pool:
As we have seen threading does a lot good, it helps us multi-task, use our hardware to it's potential but thread creation and management is expensive. Moreover you would not like to instantiate 1 thread for every small task that you do, be it serving a web request or some other kind of computation task.
A thread pool as the name suggests is basically a managed collection of threads. It could be programmer managed or it could be system managed (depends on how and what you instantiate; we will see in my examples that follow). Besides taking away the overhead of thread creation and destruction, the biggest advantage of thread pool is basically use of producer-consumer concept. What this means is just like any other object pool, thread pooling allows your program to keep assigning new tasks to a thread when its done processing the existing task. This way you end up utilizing the system optimally and in a controlled fashion without over stressing it (just imaging if you created 1 thread for every request with 600-700 active clients you would end up running out of system resources way before you meet the demands)

Java implements thread pools using Executor service.

ExecutorService service=Executors.newFixedThreadPool(10);
//10 refers to the number of threads in the pool


(to be continued.............keep reading)

Comments

Popular Posts