What is Multitreading?

Multithreading is the ability of an operating system to execute different parts of a program (Thread) simultaneously.

In case of single threaded application when we invoke a method, at that time the caller waits for the called function. And it pauses the execution of caller function. So a normal method call is not gonna work to implement a multithreaded environment. Multithreading can be done by using a library package – java.lang.

Way to invoke a Thread is very simple. There is one interface named Runnable which gives you public void run() method which will be executed in parallel. But who will invoke it? Of course we cannot. Invocation part is handled by Thread class which is derived from Runnable itself. ultimately we will need both the entities. 1) Runnable 2) Thread. So there are 2 ways to have multiple threads in your application.

Ways to create a Multithreaded application

  1. Implementing java.lang.Runnable interface

    In this case: As we are implementing Runnable interface, we need to compulsory write the run() method in our class. And We also need to create the object of Thread class so that threadobj.run() can be invoked.

  2. Extending java.lang.Thread class

    In this case: As Thread is derived from Runnable and we are deriving our class from Thread, we are suppose to override the run() method which is blankly defined in Thread. And to invoke it, we do not need any extra object. We will just say start();

What will be executed in parallel?

There are 4 different approaches which can be followed for a multithreaded program. “Code Block 1″ and “Code Block 2″ will be executed in parallel.

1. Runnable implementation and object of Thread in the same class

class ThreadDemo1 implements Runnable
{
	Thread t;
	ThreadDemo1()
	{
		t = new Thread(this);
		t.start();
		-----------------------------
		|							|
		|							|
		|		Code Block 1		|
		|							|
		|							|
		-----------------------------
	}	
	public void run()
	{
		-----------------------------
		|							|
		|							|
		|		Code Block 2		|
		|							|
		|							|
		-----------------------------
		
	}
	public static void main(String[] s)
	{
		new ThreadDemo1();	
	}
}

2. Runnable implementation and object of Thread in the different classes

class ThreadDemo2
{
	Thread t;
	ThreadDemo2()
	{
		otherClass obj = new otherClass();
		t = new Thread(obj);
		t.start();
		-----------------------------
		|							|
		|							|
		|		Code Block 1		|
		|							|
		|							|
		-----------------------------
	}	
	
	public static void main(String[] s)
	{
		new ThreadDemo2();	
	}
}

class otherClass implements Runnable
{
	public void run()
	{
		-----------------------------
		|							|
		|							|
		|		Code Block 2		|
		|							|
		|							|
		-----------------------------
		
	}
}

3. Extending Thread class

class ThreadDemo3 extends Thread
{
	ThreadDemo3()
	{
		start();
		-----------------------------
		|							|
		|							|
		|		Code Block 1		|
		|							|
		|							|
		-----------------------------
	}	
	public void run()
	{
		-----------------------------
		|							|
		|							|
		|		Code Block 2		|
		|							|
		|							|
		-----------------------------
		
	}	
	public static void main(String[] s)
	{
		new ThreadDemo3();	
	}
}

4. Extending Thread in other class

class ThreadDemo4
{
	ThreadDemo4()
	{
		otherClass oc = new otherClass();
		oc.start();
		-----------------------------
		|							|
		|							|
		|		Code Block 1		|
		|							|
		|							|
		-----------------------------
	}	
	public static void main(String[] s)
	{
		new ThreadDemo4();	
	}
}
class otherClass extends Thread
{
	public void run()
	{
		-----------------------------
		|							|
		|							|
		|		Code Block 2		|
		|							|
		|							|
		-----------------------------
	}	
		
}


Note: What we understood by this tutorial is: Code written in “Code Block 1″ and “Code Block 2″ will be executed in parallel. You might have noticed that in each tutorial we are creating an anonymous object of main class. Why? The reason is: main() method is static and we are deriving main class from Runnable/Thread which are not having static methods. That means memory for main() method will be allocated even though we do not create any object of main class but memory for non-static methods/variables will be only given when we create an object. So, in above pseudo code we have created anonymous object to do the same. Constructors are always non-static and in that we can access other non-static methods/variable.