Reading:  

Quick walk through the advanced concepts in Java - Part 3 of series


Multithreading

Multithreading is a process of executing multiple threads simultaneously. Thread is a smallest unit of processing. Both Multiprocessing and multithreading are used to achieve multitasking. Multitasking is when multiple tasks share common resources for processing like CPU. Multithreading extends the idea of multitasking into applications where it can subdivide particular operations within application into individual threads where these threads can run parallel.

Thread State Cycle:

A thread has many stages in its life cycle. For example: new, runnable, waiting and terminate.

 

 

Stages:

  • New: It is a born state of thread which remains in thisstate until the program starts the thread.
  • Runnable: After the thread is started, the thread goes to runnable state.
  • Waiting: In this state the thread waits for another thread to perform an operation.
  • Timed waiting:For a specified time of interval where a runnable thread can go to timed waiting state. In this state a thread back to the runnable state when the specified time expires.
  • Terminated:When thread completes its task a runnable thread enters the terminated state.

Thread Priorities:

Every thread has a priority whichmainly helps the OS to get the order of scheduled threads.

Priorities of Thread:

  • NORM_PRIORITY (a constant of 5) by default every thread is given priority.
  • MIN_PRIORITY (a constant of 1)
  • MAX_PRIORITY (a constant of 10).

 

To create thread:

  • By implementing Runnable interface
  • By extending Thread class

By Implementing Runnable Interface:

Follow below procedure:

  • To implement a run() method provided by interfaceRunnablewhich provides entry point for the thread and where user need to add business logic into this method.
  • Need to instantiate a Thread object using the constructor
  • After creating Thread object, now need to start it by calling start( ) method, which executes a call to run( ) method.

Example:

public class ByRunnable implements Runnable {

	public void run() {
		System.out.println("By implementing Runnable interface");
	}

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

Output:

 

By Extending Thread Class:

Thread class gives methods and constructors to create and perform tasks on a thread

Need to override method run( ) of Thread class which gives entry point for the thread and for the thread and where user need to add business logic into this method.Follow below procedure:

  • After creating Thread object, now need to start it by calling start( ) method, which executes call to run( ) method.

Example:

public class ByThread extends Thread{
	public void run(){  
		System.out.println("By extending Thread class");  
		}  
		public static void main(String args[]){  
		ByThread t1=new ByThread();  
		t1.start();  
		}
}
 

Output

Methods of Thread class:

  • public String getName(): returns the threadname
  • public void start(): starts the thread execution
  • public int getPriority(): returns the thread priority
  • public String getName(): returns the thread name
  • public int getId(): returns the thread id
  • public void join(): waits for a thread to die
  • public void sleep(long miliseconds): temporarily cease execution pause thethread execution for the specified milliseconds
  • public void run(): to perform operation for a thread
  • public int setPriority(int p): to change the thread priority
  • public void setName(String str1): changes the thread name
  • public Thread.StategetState(): returns the thread state
  • public void interrupt(): interrupts the thread
  • public boolean isAlive(): checks if the thread is alive
  • public Thread currentThread(): returns the currently executing thread reference
  • public void yield(): pausetemporarily the currently executing thread object and allow other threads to execute
  • public void setDaemon(boolean b): Tomarks the thread as daemon/user thread
  • public boolean isDaemon(): checks if a thread is a daemon or not
  • public void resume(): to resume the thread which is suspended
  • public void suspend(): to suspend the thread
  • public void stop(): to stop the execution of thread

Example by using few above methods:

public class TestThreadAextends Thread {
	public void run() {

		System.out.println("thread priority is:" + Thread.currentThread().getPriority());
	}

	public static void main(String[] args) {
		TestThreadA a1 = newTestThreadA();
		TestThreadA a2 = newTestThreadA();
		a1.setPriority(Thread.MIN_PRIORITY);
		a2.setPriority(Thread.MAX_PRIORITY);
		System.out.println("a1 name: " + a1.getName());
		System.out.println("a2 name: " + a2.getName());
		a1.start();
		a2.start();
		a1.setName("Java_thread");
		System.out.println("After name changing of a1: " + a1.getName());
	}
}

Output

 

Synchronization in Java

Within a program we can start two or more threads, in some situation multiple threads try to access the same resource they may produce unforeseen output due to concurrency issue. Toovercome this problem java provides us synchronization.

Synchronization is the capability of control the access of multiple threads to shared resource.It is good option to allow only one thread to access the shared resource.

What is the use of Synchronization?

  • To avoid consistency problem
  • To avoid thread interference

Synchronization types:

There are two types:

  • Thread Synchronization
  • Process Synchronization

Multithreading example without Synchronization:

classWithoutSynchronization {
	void table(int s) { // not synchronized method
		for (inti = 1; i <= 5; i++) {
			System.out.println(s * i);
			try {
				Thread.sleep(400);
			} catch (Exception e) {
				System.out.println(e);
			}
		}
	}
}
class Thread1Exm extends Thread {
	WithoutSynchronization t;
	Thread1Exm(WithoutSynchronization t) {
		this.t = t;
	}
	publicvoid run() {
		t.table(5);
	}
}
class Thread2Exm extends Thread {
	WithoutSynchronization t;
	Thread2Exm(WithoutSynchronization t) {
		this.t = t;
	}
	publicvoid run() {
		t.table(100);
	}
}

class Synchron1Test {
	publicstaticvoid main(String args[]) {
		WithoutSynchronization o = new WithoutSynchronization();
		Thread1Exm thread1 = new Thread1Exm(o);
		Thread2Exm thread2 = new Thread2Exm(o);
		thread1.start();
		thread2.start();
	}
}

 

Whenever we run the program produces different result:

First time executed output:

Second time executed output:

Multithreading example with Synchronization:

class WithSynchronization {
	synchronized void table(int s) { // synchronized  method
		for (inti = 1; i <= 5; i++) {
			System.out.println(s * i);
			try {
				Thread.sleep(400);
			} catch (Exception e) {
				System.out.println(e);
			}
		}

	}
}

class ExmThread1 extends Thread {
	WithSynchronization t;
	ExmThread1(WithSynchronization t) {
		this.t = t;
	}
	public void run() {
		t.table(5);
	}

}
class ExmThread2 extends Thread {
	WithSynchronization t;
	ExmThread2(WithSynchronization t) {
		this.t = t;
	}
	public void run() {
		t.table(100);
	}
}

class TestWithSynchron1 {
	public static void main(String args[]) {
		WithSynchronization o = new WithSynchronization();
		ExmThread1 thread1 = new ExmThread1(o);
		ExmThread2 thread2 = new ExmThread2(o);
		thread1.start();
		thread2.start();
	}
}

 

Whenever we run the program produces same result:

Inter-thread communication in Java:

Inter-thread communication is allowsfor communication of synchronized threads with each other.

It is a process in which paused a thread execution in its critical section and allows to other thread to enter in the same critical section to be executed.

Methods are:

  • wait()
  • notify()
  • notifyAll()

wait():

Causes current thread to wait until either another thread invokes the notifyAll()method or the notify() method for a specified amount of time has elapsed.

notify():

Wakes up a single thread which is waiting on the object's monitor

notifyAll():

Wakes up entire threads which are all waiting on this object's monitor

Example by using above methods:

public class payment {
	int amt = 3000;

	synchronized void paymentOption(intamt) {
		System.out.println("Selected payment option...");

		if (this.amt < amt) {
			System.out.println("*** Insufficient balance : Payment Failed ***");
			try {
				wait(); //to make thread to wait
			} catch (Exception e) {}
		}
		this.amt -= amt;
		System.out.println("Payment done!!!");
	}

	synchronized void depositMoney(intamt) {
		this.amt += amt;
		System.out.println("Deposition process completed succefully... ");
		notify();
	}
}

class Run {
	public static void main(String args[]) {
		final payment p = new payment();
		new Thread() {
			public void run() {
				p.paymentOption(8000);
			}
		}.start();
		new Thread() {
			public void run() {
				p.depositMoney(10000);
			}
		}.start();
	}
}


Output

Java - Thread Deadlock:

Deadlock is a state of execution where two or more threads are trying to access the same resource and hence waiting each other to release so none of threads can move forward this situation is called deadlock. 

Example for Deadlock:

public class ExampleDeadLock {
	public static void main(String[] args) {
		final String firstResource = "resource1";
		final String secondResource = "resource2";
		// thread a1 trying to lock firstResource then secondResource
		Thread a1 = new Thread() {
			public void run() {
				synchronized(firstResource) {
					System.out.println("Thread 1: Locked First Resource ");

					try {
						Thread.sleep(90);
					} catch (Exception e) {}

					synchronized(secondResource) {
						System.out.println("Thread 1: Locked Second Resource ");
					}
				}
			}
		};

		// thread a2 trying to lock secondResource then firstResource
		Thread a2 = new Thread() {
			public void run() {
				synchronized(secondResource) {
					System.out.println("Thread 2: Locked Second Resource ");

					try {
						Thread.sleep(90);
					} catch (Exception e) {}

					synchronized(firstResource) {
						System.out.println("Thread 2: Locked First Resource ");
					}
				}
			}
		};
		a1.start();
		a2.start();
	}
}

Output

 

 

Description

This is the last part in our tutorial series on Java. This tutorial is designed as a quick walk through the advanced concepts of Java Languages. This tutorial is subdivided into few chapters as shown below

  1. Data Structures
  2. Collections
  3. Generics
  4. Serialization
  5. Networking 
  6. Working with Emails
  7. Multithreading
  8. Getting started with Applets
  9. JavaDoc

Let us know if you find any issues with this tutorial. Also, if you can provide us with your feedback, that always help us improve.

 



Prerequisites

You must have read Part 1 and Part 2 of our tutorial series on Java.

Audience

Beginners or students looking to brush up their Java knowledge

Learning Objectives

To get an understanding on some of the advanced topics of Java.

Author: Subject Coach
Added on: 10th Mar 2015

You must be logged in as Student to ask a Question.

None just yet!