Threads Synchronization
Threads Synchronization
1. Thread Introduction
2. Difference between Multiprocessing and Multithreading
3. Thread Life cycle(The States of the Thread)
Thread Introduction
An instance of Thread class is just an object, like any other object in java. But a
thread of execution means an individual "lightweight" process that has its own
call stack. In java each thread has its own call stack.
Difference between Multiprocessing and Multithreading
A thread can be in one of the several states. In general terms, a thread can
running. It can be ready to run as soon as it gets the CPU time. A running thread
can be suspended, which is a temporary halt to its execution. It can later be
resumed. A thread can be blocked when waiting for the resource. A thread can
be terminated.
New State: When we create a thread it is said to be in the new born state. At
this state we can schedule it for running using the start() method or to Kill it
using stop() method.
Runnable State: A runnable state means that a thread is ready for execution
and waiting for the availability of the processor. That is the thread has joined
the queue of the threads for execution. If all the threads have equal priority,
then they are given time slots for execution in the round rabin fashion, first-
come, first-serve manner.
Running state: Running state means that the processor has given its time to the
thread for it execution. The thread runs until it relinquishes the control or it is
preempted by the other higher priority thread. A running thread can be
preempted using the suspen(), or wait(), or sleep() methods.
Blocked state: A thread is said to be in the blocked state when it is prevented
from entering into runnable state and subsequently the running state.
terminated state: Every thread has a life cycle. A running thread ends its life
when it has completed execution. It is a natural death. However we also can kill
the thread by sending the stop() message to it at any time.
Thread methods
try
{
for(int n=5;n>0;n--)
{
System.out.println(n);
Thread.sleep(1000);
}}
catch (InterruptedException e)
{
System.out.println("Main thread interrupted");
}}}
Creation of Thread
Creating the threads in the Java is simple. The threads can be implemented
in the form of object that contains a method "run()". The "run()" method is the
heart and soul of any thread. It makes up the entire body of the thread and is the
only method in which the thread behavior can be implemented. There are two
ways to create thread.
The Runnable interface contains the run() method that is required for
implementing the threads in our program. To do this we must perform the
following steps:
import java.io.*;
import java.util.Scanner; public static void main(String[]args)
{
class one extends Thread one o=new one();
{ one oo=new one();
public void run()
{
try try
{ {
for(int i=0;i<=3;i++) o.start();
{ o.join();
System.out.println("Value of i=:"+i); //o.start();
Thread.sleep(1000); oo.start();
} }
} catch(InterruptedException e)
catch(InterruptedException e) {
{ System.out.println(e);
System.out.println(e); }}}
}}
Creating Multiple Threads
// example 2
class one
class A extends Thread {
{ public static void main(String[]args)
public void run() {
{
System.out.println(Thread.currentThr try
ead().getPriority()); {
System.out.println("Thread A"); A AA=new A();
} AA.setPriority(Thread.MIN_PRIORITY);
} B BB=new B();
BB.setPriority(Thread.MAX_PRIORITY);
class B extends Thread C CC=new C();
{ CC.setPriority(Thread.NORM_PRIORITY
public void run() );
{ AA.start();
System.out.println(Thread.currentThr AA.join();
ead().getPriority()); BB.start();
System.out.println("Thread B"); BB.join();
} CC.start();
} }
catch(InterruptedException e)
class C extends Thread {
{ System.out.println(e);
public void run() }}}
{
System.out.println(Thread.currentThr
ead().getPriority());
System.out.println("Thread C");
}}
// Another Example public void run()
import java.io.*; {
class xyz implements Runnable try
{ {
String str1; for(int i=0;i<=3;i++)
Thread t; {
xyz(String str2) System.out.println("Value of
{ i=:"+i);
try Thread.sleep(1000);
{ }}
str1=str2; catch(InterruptedException e)
t=new Thread(this,str1); {
t.start(); System.out.println(e);
t.setPriority(Thread.MAX_PRIORITY); }
System.out.println(t.isAlive()); }
t.join(); }
System.out.println("Thread=:"+t.getName());
System.out.println(t.getPriority());
System.out.println(t.getId());
System.out.println("Thread Completed"); class one
System.out.println("Thread Position {
:"+t.isAlive()); public static void main(String
Thread.sleep(1000);} []args)
catch(InterruptedException e) {
{ xyz xx=new xyz("aa");
System.out.println(e); xyz xxx=new xyz("bbb");
}} }}
Synchronization
When two or more threads need access to a shared resource, they need
to ensure that the resource will be used by only one thread at a time. The
process by which this is achieved is called synchronization
//without the synchronization class MyThread2 extends Thread
class Table {
{ Table t;
void printTable(int n)
{ MyThread2(Table t)
for(int i=1;i<=5;i++) {
{ this.t=t;
System.out.println(n*i); }
try
{ public void run()
Thread.sleep(400); {
} t.printTable(100);
}
catch(InterruptedException ie) }
{
System.out.println("The Exception is
:"+ie);
}}}} class one
class MyThread1 extends Thread {
{ public static void main(String args[])
Table t; {
MyThread1(Table t) Table obj = new Table();
{ MyThread1 t1=new MyThread1(obj);
this.t=t; MyThread2 t2=new MyThread2(obj);
} t1.start();
public void run() t2.start();
{ }
t.printTable(5); }
}}
Using the Java synchronized method
Synchronized method is used to lock an object for any shared resource. When
a thread invokes a synchronized method, it automatically acquires the lock for
that object and releases it when the thread completes its task. The general
form of the synchronized method is:
Syntax : synchronized type method_name(para_list)
{
//body of the method
}
// Using the Java synchronized public void run()
method {
t.printTable(5);
class Table }}
{ class MyThread2 extends Thread
synchronized void printTable(int n) {
{ Table t;
for(int i=1;i<=5;i++) MyThread2(Table t)
{ {
System.out.println(n*i); this.t=t;
try }
{ public void run()
Thread.sleep(400); } {
catch(InterruptedException ie) t.printTable(100);
{ }}
System.out.println("The Exception is class one
:"+ie); {
}}}} public static void main(String args[])
class MyThread1 extends Thread {
{ Table obj = new Table();
Table t; MyThread1 t1=new MyThread1(obj);
MyThread1(Table t) MyThread2 t2=new MyThread2(obj);
{ t1.start();
this.t=t; t2.start();
} }}
Note:
Inter-Thread Communication
If two or more Threads are communicating with each other, it is called "inter
thread" communication. Using the synchronized method, two or more threads
can communicate indirectly. Through, synchronized method, each thread always
competes for the resource. This way of competing is called polling. The polling
wastes the much of the CPU valuable time. The better solution to this problem is,
just notify other threads for the resource, when the current thread has finished its
task. This is explicit communication between the threads.
Java addresses this polling problem, using via wait(), notify(), and notifyAll()
methods. These methods are implemented as final methods in Object, so all
classes have them. All three methods can be called only from within a
synchronized context.
wait( ) : It tells the calling thread to give up the lock and go to sleep until some
other thread enters the same monitor and calls notify(). The wait() method
releases the lock prior to waiting and reacquires the lock prior to returning from
the wait() method. The wait() method is actually tightly integrated with the
synchronization lock, using a feature not available directly from the
synchronization mechanism.
synchronized( lockObject )
{
while( ! condition )
{
lockObject.wait();
}
synchronized(lockObject)
{
//establish_the_condition;
lockObject.notify();
notifyAll : It wakes up all the threads that called wait() on the same object. The
highest priority thread will run first in most of the situation, though not
guaranteed. Other things are same as notify() method above.
synchronized(lockObject)
{
establish_the_condition;
lockObject.notifyAll();
}
//Diff.between lock Vs Sleep public static void main(String []args)
// example 1 {
class one one o=new one();
{ try
Object LOCK = new Object(); {
void sleepWaitExamples() throws o.sleepWaitExamples() ;
InterruptedException }
{ catch(InterruptedException e)
Thread.sleep(1000); {
System.out.println("Thread '" + System.out.println(e);
Thread.currentThread().getName() +"' }
is woken after }
}
sleeping for 1 second");
synchronized (LOCK)
{
LOCK.wait(1000);
System.out.println("Object '" + LOCK +
"' is woken after" + " waiting for 1
second");
}}
Thread.stop();
This method causes a thread to move from running to dead state. A
thread will also move to dead state automatically when it reaches the end of
its method. Blocking Thread . A thread can be temporarily suspended or
blocked from entering into the runnable and running state by using the
following methods:
These methods cause the thread to go into the blocked state. The thread
will return to the runnable state when the specified time is elapsed in the case of
sleep(), the resume() method is invoked in the case of suspend(), and the notify()
method is called in the case of wait().
Thread Exceptions
Note that a call to the sleep() method is always enclosed in try/ catch block.
This is necessary because the sleep() method throws an exception, which
should be caught. If we fail to catch the exception the program will not compile.
try
{
Thread.sleep(1000); }
cathc(Exception e)
{
--------
}