Alphalearningschool
        

<<< Prev

Next >>>

Up
Java Multithreading

It is the process of executing multiple threads simultaneously, threads are light in weight .we will discuss more about multithreading before understanding multithreading let us quickly review multitasking.

Multitasking

Executing multiple tasks at a time or more than one task simultaneously is called multithreading

There are two types of multitasking

    • Process based multitasking

Executing multiple tasks simultaneously is called process based multitasking for Example while typing java program in our system we can listen song and also we can download file from internet.

    • Thread based multitasking

Executing multiple tasks concurrently is called thread based multitasking. Here each task is separate independent part of a single process. That part is called Thread.

Advantage of Multitasking:

The main advantage of multitasking is to improve the performance of the system by decreasing the response time either it is a thread based or process based multitasking.

Process based multitasking is called just multitasking and thread based multitasking is called Multithreading.

Multithreading is light weight and the context switching between two threads is fast because each thread will share same memory area.

Thread Life Cycle

Thread Life Cycle

A thread goes through various stages of life cycle like born, started, runs and dies.

Below diagram shows the thread life cycle steps:-

New: thread begins its life cycle new state and it will be in same state until the program starts the thread.

Runnable: A thread is ready to run is moved to runnable state .Any instance of time thread might be ready to run .It is the responsibility of thread scheduler to give the thread time.

Running: When Thread is executing .It state is changed to Running. Thread scheduler picks one of the threads from the thread pool. The CPU starts run these threads from thread pool. After running thread might goes to waiting state or else it will go to dead state.

Waiting: The thread waits for other thread to finish it. It can be waiting for some resources to available.

Dead: Once the thread completes its state change to Dead State.

Thread Priorities:

Every Thread has a priority which is helpful for operating system to determine the order in which threads are scheduled.

 Thread class defines 3 Constants:

1) public static int MIN_PRIORITY

2) public static int NORM_PRIORITY

3) public static int MAX_PRIORITY

The value of MAX_PRIORITY  is 10  ,MIN_PRIORITY is 1   and the NORM_PRIORITY is 5 that is  the Default priority of any thread.

Example of Thread priority: 

public class TestMultipleThreadPriority extends Thread {

	public void run() {
       System.out.println("Thread Name is : " + Thread.currentThread().getName());
       System.out.println("Thread Priority is : " + Thread.currentThread().getPriority());

	}

	public static void main(String[] args) {
		TestMultipleThreadPriority tmt1 = new TestMultipleThreadPriority();
		TestMultipleThreadPriority tmt2 = new TestMultipleThreadPriority();
		tmt1.setPriority(MIN_PRIORITY);
		tmt2.setPriority(MAX_PRIORITY);
		tmt1.start();
		tmt2.start();

	}

}

Output:
Thread Name is : Thread-1
Thread Priority is : 10
Thread Name is : Thread-0
Thread Priority is : 1

 

Note: Here Thread tmt2 is executing first because thread tmt2 has higher priority and tmt1 has lower priority.

Example of Default threads priority: 

public class TestMultipleThreadPriority extends Thread {

	public void run() {
		System.out.println("Thread Name is : " + Thread.currentThread().getName());
		System.out.println("Thread Priority is : " + Thread.currentThread().getPriority());

	}

	public static void main(String[] args) {
		TestMultipleThreadPriority thread1 = new TestMultipleThreadPriority();
		TestMultipleThreadPriority thread2 = new TestMultipleThreadPriority();
		
		thread1.setPriority(Thread.MIN_PRIORITY);
		thread1.start();
		thread2.start();

	}

}
Output 
Thread Name is : Thread-1
Thread Priority is : 5
Thread Name is : Thread-0
Thread Priority is : 1

 

Note:In the above program thread1 has MIN _PRIORITY as you are seeing but for thread2 has no priority it will take default priority and the default priority value is 5 that’s why thread2 is executing first.

How to create Thread

There are 2 ways to create thread

1) By Executing Thread class 

2) By implementing Runnable interface

 

Thread class: thread class provides lot of methods and constructor to perform operations on thread.

Constructors of Thread class:

Thread()

Thread(String name)

Thread(Runnable r)

Thread(Runnable r,String name)

Methods of thread class:

  1. public void run(): is used to perform action for a thread.
  2. public void start(): starts the execution of the thread.JVM calls the run() method on the thread.
  3. public void sleep(long miliseconds):  sleep() method of Thread class is used to sleep a thread for specific time .
  4. public void join(): waits for a thread to die.
  5. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
  6. public int getPriority(): returns the priority of the thread.
  7. public int setPriority(int priority): changes the priority of the thread.
  8. public String getName(): returns the name of the thread.
  9. public void setName(String name): changes the name of the thread.
  10. public Thread currentThread(): returns the reference of currently executing thread.
  11. public int getId(): returns the id of the thread.
  12. public Thread.State getState(): returns the state of the thread.
  13. public boolean isAlive(): tests if the thread is alive.
  14. public void yield(): causes the currently executing thread object to temporarily pause and allow other threads to execute.
  15. public void suspend(): is used to suspend the thread(depricated).
  16. public void resume(): is used to resume the suspended thread(depricated).
  17. public void stop(): is used to stop the thread(depricated).
  18. public boolean isDaemon(): tests if the thread is a daemon thread.
  19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
  20. public void interrupt(): interrupts the thread.
  21. public boolean isInterrupted(): tests if the thread has been interrupted.
  22. public static boolean interrupted(): tests if the current thread has been interrupted.

Java thread Example by extending Thread class:

public class ByExtendingThread extends Thread {
	public void run() {
	System.out.println("thread is running...");	
	}
	public static void main(String[] args) {
		ByExtendingThread th=new ByExtendingThread();
		th.start();
	}

}
Output:
thread is running...

 

Runnable interface:

Runnable interface should be implemented by the class where you want to create thread .Runnable interface have run() method only. Creating thread by implementing runnable interface is the better way.

Java thread Example by extending Thread class: 

public class ByImplementingRunnable implements Runnable {

	public static void main(String[] args) {
		ByImplementingRunnable t = new ByImplementingRunnable();
		Thread th = new Thread(t);
		th.start();
	}

	@Override
	public void run() {
		System.out.println("Thread is running...");

	}
}

Output:
Thread is running...

 

Sleep()method of Thread class: 

It is used to sleep the thread for specified amount of time .There are 2 ways to declare sleep() method. 

public static void sleep(long milliseconds)throws InterruptedException 

public static void sleep(long milliseconds,int nanos)throws InterruptedException 

Example of sleep() method of Thread class:

public class SleepMethod extends Thread {
	
	public void run() {
		for(int i=1;i<=4;i++) {
		try {
			Thread.sleep(500);
		}catch (InterruptedException ie) {
		
		}
		System.out.println(i);
	}
	}
	public static void main(String[] args) {
		SleepMethod th1=new SleepMethod();
		SleepMethod th2=new SleepMethod();
		th1.start();
		th2.start();
	}

}

Output:
       1
       1
       2
       2
       3
       3
       4
       4

 

Note:  At a time only thread will be execute according to the time which is specified by the sleep method.

join() method of Thread class 

join() method waits for a Thread to die .It means After completion of Thread execution it will give the resource to another thread. 

Syntax: 

public final void join()throws InterruptedException  

public void join(long millis)throwsInterruptedException   

Example of join() method:

public class JoinMethodTest extends Thread {
	
	public void run() {
		for(int i=1;i<=4;i++) {
			System.out.println(i);
		}
	}
	public static void main(String[] args) throws InterruptedException {
	
		JoinMethodTest tmt1=new JoinMethodTest();
		JoinMethodTest tmt2=new JoinMethodTest();
		JoinMethodTest tmt3=new JoinMethodTest();
		tmt1.start();
		try {
			tmt1.join();
		}catch (Exception e) {
          System.out.println(e);		}
		tmt2.start();
		tmt3.start();

	}

}

Output:
1
2
3
4
1
2
1
2
3
4
3
4

Note: Here join method is using with tmt1 thread reference it means after completion of thread tmt1 other threads like tmt2 and tmt3 will be execute simultaneously. In the output you can observe after completion of thread tmt1 other threads are executing. 

Naming thread and current Thread: 

In Thread class methods are available to know the thread name and set the thread name. By default each thread has a name like Thread-0, Thread-1. 

Syntax: 

public String getName(): is used to return the name of a thread.

public void setName(String name): is used to change the name of a thread. 

Example of getName() and setName() method:

public class ThreadName extends Thread {
	
	public void run() {
		System.out.println("Thread is running.....");
	}

	public static void main(String[] args) {
		ThreadName thread1=new ThreadName();
		System.out.println("Thread name of thread1: "+thread1.getName());
		
		ThreadName thread2=new ThreadName();
		System.out.println("Thread name of Thread2: "+thread2.getName());
		
		thread1.start();
		thread2.start();
		
		//set the thread name 
		thread1.setName("ABC");
		System.out.println("Name of thread1 is change to: "+thread1.getName());
	}
}

Output:

Thread name of thread1: Thread-0
Thread name of Thread2: Thread-1
Name of thread1 is change to: ABC
Thread is running.....
Thread is running.....

 

Daemon Thread in java: 

Java allows us to create two types of thread

  • Non-Daemon Threads
  • Daemon Threads 

A thread that executes main logic of the project is called non-daemon thread.

A thread that is running in background to provide services to non-daemon threads is called daemon thread.

So we can say Daemon Threads are service threads. 

Since daemon threads are service threads, its execution is execution is terminated if all non-daemon threads execution is completed. Daemon Threads are low priority thread. 

Methods for java daemon Threads: 

  • Public void setDaemon(boolean status) : It is used to set the current thread as a Daemon thread.
  • Public boolean isDaemon() : It is used to check that Thread is Daemon or not. 

Example of Daemon Thread:

public class DaemonThread extends Thread {
	
	public void run() {
		if(Thread.currentThread().isDaemon()) {
			System.out.println("Daemon Thread is running...");
		}
		else {
			System.out.println("User thread is running....");
		}
		
	}
	
	public static void main(String[] args) {
		DaemonThread dt =new DaemonThread();
		DaemonThread dt1 =new DaemonThread();
		dt.setDaemon(true);
		dt.start();
		dt1.start();

         //It will throw IllegalThreadStateException
         // dt.start();
        //dt.setDaemon(true);

	}

}

Output:

Daemon Thread is running...
User thread is running....

 

Note : if we want to make user thread as Daemon thread .It must not be started otherwise it will throw IllegalThreadStateException.

 

Garbage Collection:

The process of destroying unreferenced object is called Garbage collection.

After object is unreferenced it is considered as unused object hence JVM automatically destroys that objects. 

Advantage of garbage collections: 

It improves Memory utilization.

It is automatically done by JVM. 

There are many ways to make the object Unreferenced. 

  • By nulling a reference:

         Student st =new Student();

          St=null;

  • By anonymous objects:

         new Student(); 

finalize() method: 

This method is used to perform some final operations or clean up operations on an object before it is removed from the memory.  you can override the finalize() method to keep those operations. 

protected void finalize(){ 

}

gc() method:

we have a method called gc() in System class as static method and also in Runtime class as non-static method to request JVM to start garbage collection Execution. 

Example of Garbage Collection:

public class GarbageCollectionClass {
	
	protected void finalize() {
		System.out.println("garbage collected...");
	}
	
	public static void main(String[] args) {
		GarbageCollectionClass gcc=new  GarbageCollectionClass();
		GarbageCollectionClass gcc1=new  GarbageCollectionClass();
		gcc=null;
		gcc1=null;
		System.gc();

	}

}
Output:
garbage collected...
garbage collected...

 

Synchronization: 

The process of allow only one thread to access the shared resource or the capability to control the access of multiple threads to any shared resource. 

In java synchronization is implemented by using synchronized keyword 

Synchronization is developed by using:

  • Synchronized methods
  • Synchronized blocks 

Difference between synchronized method and block:

     1)  If method is declared as synchronized that methods complete logic is executed in sequence from multiple threads by using same object.

 

1)If we declared block as synchronized, only the statements written inside the block are executed sequentially not completed method logic. 

2) Using synchronized method we can only lock current object of the method.

2)Using synchronized block we can lock either current object or argument object of the method.

Example of Synchronized method: 

class AddClass {
	int x, y;

	//void add(int x, int y) {
	synchronized void add(int x,int y) {	
		this.x = x;
		this.y = y;
		try {
			Thread.sleep(400);
		} catch (Exception e) {
			e.printStackTrace();
		}
		int result=this.x+this.y;
		System.out.println("In "+Thread.currentThread().getName()+" Result : "+result);
	}
}
class Thread1 extends Thread{
	AddClass ac;
	Thread1(AddClass ac){
		this.ac=ac;
	}
	public void run() {
		ac.add(50, 60);
	}
}
class Thread2 extends Thread{
	AddClass ac;
	Thread2(AddClass ac){
		this.ac=ac;
	}
	public void run() {
		ac.add(80, 90);
	}
}


public class synchronizedMethodExample {
	public static void main(String[] args) {
 
		AddClass a=new AddClass();
		new Thread1(a).start();
		new Thread2(a).start();
	}

}
 
Output:
In Thread-0 Result: 110
In Thread-1 Result: 170

Note: uncomment and use non synchronized method it will give output
In Thread-0 Result: 170
In Thread-1 Result: 170

 

Example of Synchronized block:

class Table{  
  
 void printTable(int n){  
  synchronized(this){//synchronized block  
     for(int i=1;i<=5;i++){  
      System.out.println(n*i);  
      try{  
       Thread.sleep(400);  
      }catch(Exception e){System.out.println(e);}  
     }  
   }  
 }//end of the method  
}  
  
class MyThread1 extends Thread{  
Table t;  
MyThread1(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(2);  
}  
  
}  
class MyThread2 extends Thread{  
Table t;  
MyThread2(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(10);  
}  
}  
  
public class TestSynchronizedBlock1{  
public static void main(String args[]){  
Table obj = new Table();//only one object  
MyThread1 t1=new MyThread1(obj);  
MyThread2 t2=new MyThread2(obj);  
t1.start();  
t2.start();  
}  
}  
Output:
10
20
30
40
50
2
4
6
8
10