Thread Creation Concept
Multithreading corresponds to multiple flows of control. It is a conceptual paradigm where we can divide a program into two or more processes that can run in parallel.Java allows us to have inbuilt processes where more than one process can be executed concurrently within a single program.
Java thread is lightweight, meaning they can run in the same memory space. They can communicate themselves(one object of one thread class can call a method of another thread without any overhead of operating system). Threads can execute independently and simultaneously.
So java handles multiple tasks simultaneously using a multi-threaded way. This feature enables to finish tasks before even beginning another.Java coding is mostly sequential single flow execution(single-threaded programming).
A thread is a single flow of control having a beginning a body and end. A thread executes commands sequentially. The ability to support multi-threads is referred to as concurrency. Since the threads in java are subprograms of the main application and share the same memory space. Even though threads appear to run parallel, it is actually sequential but very fast switching of control between threads.
Once initiated by the main program, Thread A, Thread B, and Thread C run independently, concurrently and share the system resources.
Java provides two way to create a thread.
- Subclassing the Thread class. Here we define a class and extend to Thread class, then override the run() method.
- Implementing the runnable interface. Here we implement the runnable interface and define the run() method.
Sub Classing to the Thread Class:
- Start a thread.
- Stop the thread.
- Suspend it temporarily
The constructor of the Thread class accepts information about where the thread should begin its execution.
- We need to declare the class as extending to the Thread class.
- Override the run() method in the subclass which is responsible for executing the sequence of code that the thread will execute.
- Create a thread object and call the start() method to initiate the thread execution.
Example:
class MyThread extends Thread{
//MyThread is a new Thread which extends to Thread Class. This subclass will contain a method called run().run()
//contains the actual task what thread should perform.
private String whichThread;
private int delay;
MyThread(String myString,int timeOut)
{
whichThread=myString;
delay=timeOut;
}
//Main method to construct thread and the only method in which thread's behavior can be written.
//Here we need to override the run() method.
public void run()
{
try{
sleep(delay);
}
catch(InterruptedException e)
{
System.out.println("A thread is interrupted");
}
finally{
System.out.println("Hello "+ whichThread+" slept "+delay);
}
}
}
public class TestThread{
public static void main(String []args){
MyThread t1,t2,t3;
//creating the object of the class we created earlier. The state of the threads will be newborn
t1=new MyThread("Thread 1",10);
t2=new MyThread("Thread 2",20);
t3=new MyThread("Thread 3",30);
//start() method to start the threads that will invoke the run() method . This will cause the threads to go to runnable state.Java run time will schedule the threads to run by invoking it's run method.
t1.start();
t2.start();
t3.start();
try{
t1.join();
t2.join();
t3.join();
}
catch(InterruptedException e)
{
}
}
}
the output of the code:
$javac TestThread.java
$java -Xmx128M -Xms16M TestThread
Hello Thread 1 slept 10
Hello Thread 2 slept 20
Hello Thread 3 slept 30
Another Example:
Once we initiate a thread with new and started them, they are running concurrently on their own. The output is not especially sequential. They just do not follow any specific order. Once the thread has been started, we can not decide in which order they may execute the statements.
class A extends Thread{
public void run()
{
for(int i=1;i<5;i++)
{
System.out.println("From Thread A "+i);
}
System.out.println("Exit from Thread A ");
}
}
class B extends Thread{
public void run()
{
for(int j=1;j<5;j++)
{
System.out.println("From Thread B "+j);
}
System.out.println("Exit from Thread B ");
}
}
class C extends Thread{
public void run()
{
for(int k=1;k<5;k++)
{
System.out.println("From Thread C "+k);
}
System.out.println("Exit from Thread C ");
}
}
public class ThraedTest{
public static void main(String args[])
{
new A().start();
new B().start();
new C().start();
}
}
the output of the code:
$javac ThraedTest.java $java -Xmx128M -Xms16M ThraedTest From Thread A 1 From Thread A 2 From Thread A 3 From Thread A 4 Exit from Thread A From Thread B 1 From Thread B 2 From Thread B 3 From Thread B 4 Exit from Thread B From Thread C 1 From Thread C 2 From Thread C 3 From Thread C 4 Exit from Thread C |
$javac ThraedTest.java $java -Xmx128M -Xms16M ThraedTest From Thread A 1 From Thread A 2 From Thread B 1 From Thread C 1 From Thread A 3 From Thread A 4 Exit from Thread A From Thread B 2 From Thread B 3 From Thread B 4 Exit from Thread B From Thread C 2 From Thread C 3 From Thread C 4 Exit from Thread C |
Using Runnable Interface:
The second way to create Thread is to make use of the runnable interface. With this approach, we need to implement the runnable interface to the class. The runnable interface is already defined in java.lang package with a single method called- run().
- Declare the class as implementing the Runnable interface.
- Implement the run() method.
- Create a thread by defining an object that is instantiated from this “runnable” class as the target of the thread.
- Call the thread’s start() method to run the thread.
Example:
class Pen implements Runnable{
private int price;
private String name;
Pen(int price,String name)
{
this.price=price;
this.name=name;
}
public void run()
{
try{
Thread.sleep(price*1000);
System.out.println("A pen "+name+" price is "+price);
}
catch(InterruptedException e)
{
System.out.println("Pen thread is interrupted");
}
}
}
class Pencil implements Runnable{
private int price;
private String name;
Pencil(int price,String name)
{
this.price=price;
this.name=name;
}
public void run()
{
try{
Thread.sleep(price*2000);
System.out.println("A Pencil "+name+" price is "+price);
}
catch(InterruptedException e)
{
System.out.println("Pencil thread is interrupted");
}
}
}
public class TestThreadRunnable{
public static void main(String []args){
Pen myPen=new Pen(2,"Lammy");
Thread t1=new Thread(myPen);
t1.start();
Pencil myPencil=new Pencil(3,"Nataraj");
Thread t2=new Thread(myPencil);
t2.start();
try{
t1.join();
t2.join();
}
catch(InterruptedException e)
{
}
}
}
the output of the code:
$javac TestThreadRunnable.java
$java -Xmx128M -Xms16M TestThreadRunnable
A pen Lammy price is 2
A Pencil Nataraj price is 3
- Program with multiple threads will result in better utilization of system resources(CPU).
- This feature improves the interactive performance of the graphical application
When to use a subclass of thread and when to use runnable?
The Thread class provides a static method called currentThread() that provides a reference to thread object that controls the current thread of execution.