THREAD
THREAD
THREAD IN JAVA
WHAT ARE JAVA THREADS?
A thread is defined as a separate stream of implementation that takes place simultaneously with and
independently of everything else that might be happening. It does not have an event loop. A thread runs
autonomously of anything else happening in the computer. With threads the other tasks that don't get stuck
in the loop can continue processing without waiting for the stuck task to terminate. A thread is a coding that
doesn't affect the architecture of an application. Threading is equally separate the computer's power among
different tasks. Threading concept is very important in Java Programing language. A thread is a sequential path
of code execution within a program. And each thread has its own local variables, program counter and
lifetime.
So, a thread is an independent path of execution within a program. Many threads can run concurrently within
a program. Every thread in Java is created and controlled by the java.lang.Thread class.
So, thread is a:
Facility to allow multiple activities within a single process.
Referred as lightweight process.
A thread is a series of executed statements.
Each thread has its own program counter, stack and local variables.
A thread is a nested sequence of method calls.
Its shares memory, files and per-process state.
WHAT IS THE NEED OF A THREAD OR WHY USE THREADS?
To perform asynchronous or background processing.
Increases the responsiveness of GUI applications.
TAKE ADVANTAGE OF MULTIPROCESSOR SYSTEMS
Simplify program logic when there are multiple independent entities.
WHAT HAPPENS WHEN A THREAD IS INVOKED?
When a thread is invoked, there will be two paths of execution. One path will execute the thread and the
other path will follow the statement after the thread invocation. There will be a separate stack and memory
space for each thread.
RISK FACTOR
Proper co-ordination is required between threads accessing common variables [use of synchronized
and volatile] for consistence view of data.
Overuse of java threads can be hazardous to program’s performance and its maintainability.
1
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
2
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
3
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
This is another way to create a thread by a new class that extends Thread class and create an
instance of that class. The extending class must override run() method which is the entry point of
new thread.
class MyThread extends Thread
{
public void run()
{
System.out.println("Concurrent thread started running..");
}
}
classMyThreadDemo
{
public static void main( String args[] )
{
MyThread mt = new MyThread();
mt.start();
}
}
Output : concurrent thread started running..
NOTE:-
In this case also, as we must override the run() and then use the start() method to start and run the thread.
Also, when you create MyThread class object, Thread class constructor will also be invoked, as it is the super
class, hence MyThread class object acts as Thread class object.
By extending Thread class:
class Multi extends Thread
{
public void run()
{
System.out.println("thread is running...");
}
public static void main(String args[])
{
Multi t1=new Multi();
t1.start();
}
}
Output: thread is running...
Note : But the problem with this approach is that class can not extend any more class,run method can be
overloaded in class. but only run() method(without argument) will be consider by JVM. Any other overridden
method will needs to be called explicitly.
5
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
6
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
7
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
• // Following is the main program which makes use of above defined classes:
public class ThreadClassDemo
{
public static void main(String [] args)
{ OUTPUT:-
Runnable hello = new DisplayMessage("Hello"); Starting hello thread...
Thread thread1 = new Thread(hello); Starting goodbye thread...
thread1.setDaemon(true); Hello
thread1.setName("hello"); Hello
System.out.println("Starting hello thread..."); Hello
thread1.start(); Hello
Runnable bye = new DisplayMessage("Goodbye"); Hello
Thread thread2 = new Thread(bye); Hello
thread2.setPriority(Thread.MIN_PRIORITY); Goodbye
thread2.setDaemon(true); Goodbye
System.out.println("Starting goodbye thread..."); Goodbye
thread2.start(); Goodbye
System.out.println("Starting thread3..."); Goodbye
Thread thread3 = new GuessANumber(27); .......
thread3.start();
try
{
thread3.join(); NOTE:-
}catch(InterruptedException e) This would produce the following result.
{ You can try this example again and again
System.out.println("Thread interrupted."); and you would get different result every
} time.
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
8
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SUBCLASS THREAD.
The Thread class itself implements Runnable, though its run method does nothing. An application can
subclass Thread, providing its own implementation of run, as in the HelloThread example:
• EXAMPLE:-
public class HelloThread extends Thread
{
public void run()
{
System.out.println("Hello from a thread!");
}
public static void main(String args[])
{
(new HelloThread()).start();
}
}
• EXAMPLE:
public class MyThread implements Runnable
{
public void run()
{
System.out.println("thread is running..");
}
public static void main(String[] args)
{
Thread t = new Thread(new MyThread());
t.start();
}
• ANOTHER EXAMPLE:-
class MyRunnable implements Runnable
{
public void run()
{
//Keep the task to be performed here
}
}
public class MainClass
{
public static void main(String[] args)
{
MyRunnable runnable = new MyRunnable();
Thread t = new Thread(runnable);
t.start();
}
}
NOTE: -The easiest way to create a thread is to create a class that implements the runnable interface. After
implementing runnable interface , the class needs to implement the run() method, which is of form,
9
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
10
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
11
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
You can extend any other class. You can’t extend any other class.
Separates the task from the runner. Doesn’t separate the task from the runner.
12
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
INSTANTIATING THREAD :
Every thread of execution begins as an instance of class Thread. In any case Thread objects needs to be
created before creating Thread of Execution.
Creating Thread object is different for both the cases. In case of Extending Thread class you can directly
initiate class with new keyword as it has extended Thread class itself.
MyThread t = new MyThread()
In case of implementing Runnable interface. First created runnable class needs to be instantiated.
MyRunnable r = new MyRunnable();
Now pass this runnable object to Thread.
Thread t = new Thread(r);
If create a thread using the no-arg constructor, the thread will call its own run(). This happened in first
case(Extending Thread class) But in case of Runnable Thread class needs to know that run method from class
implementing runnable interface needs to be invoked instead of run() from Thread class. So we need to pass
the class as argument to Thread.
Single runnable instance can be passed to multiple Thread object.
public class TestThreads
{
public static void main (String [] args)
{
MyRunnable r = new MyRunnable();
Thread foo = new Thread(r);
Thread bar = new Thread(r);
Thread bat = new Thread(r);
}
}
NOTE : Giving the same target to multiple threads means that several threads of execution will be running the
very same job .The Thread class itself implements Runnable. (After all, it has a run() method that we were
overriding.) This means that you could pass a Thread to another Thread’s constructor.
METHOD DESCRIPTION
setName() to give thread a name
14
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
15
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
16
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
JOINING THREADS
• Sometimes one thread needs to know when another thread is ending. In java, isAlive() and join() are
two different methods to check whether a thread has finished its execution.
• The isAlive() methods return true if the thread upon which it is called is still running otherwise it
return false.
final boolean isAlive()
But, join() method is used more commonly than isAlive(). This method waits until the thread on which it is
called terminates.
final void join() throws InterruptedException
Using join() method, we tell our thread to wait until the specified thread completes its execution. There are
overloaded versions of join() method, which allows us to specify time for which you want to wait for the
specified thread to terminate.
final void join(long milliseconds) throws InterruptedException
Example of isAlive method
public class MyThread extends Thread
{
public void run()
{
System.out.println("r1 ");
try
{
Thread.sleep(500); Output
} catch(InterruptedException ie) { } r1
System.out.println("r2 "); true
} true
public static void main(String[] args) r1
{ r2
MyThread t1=new MyThread(); r2
MyThread t2=new MyThread();
t1.start();
t2.start();
System.out.println(t1.isAlive());
System.out.println(t2.isAlive());
}
}
Example of thread without join() method
public class MyThread extends Thread
{ Output
public void run() r1
{ r1
System.out.println("r1 "); r2
try r2
{
Thread.sleep(500);
} catch(InterruptedException ie) { }
System.out.println("r2 ");
}
17
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
18
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
19
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
catch(Exception e)
{ Output:
System.out.println(e); 1
} 2
System.out.println(i); 3
} 1
} 4
public static void main(String args[]) 1
{ 2
TestJoinMethod2 t1=new TestJoinMethod2(); 5
TestJoinMethod2 t2=new TestJoinMethod2(); 2
TestJoinMethod2 t3=new TestJoinMethod2(); 3
t1.start(); 3
try 4
{ 4
t1.join(1500); 5
} 5
catch(Exception e)
{
System.out.println(e);
}
t2.start();
t3.start();
}
}
NOTE:- In the above example,when t1 is completes its task for 1500 miliseconds(3 times) then t2 and t3
starts executing.
A thread invokes the join() method on another thread in order to wait for the other thread to
complete its execution.Consider a thread t1 invokes the method join() on a thread t2. The join() call
has no effect if thread t2 has already completed. If thread t2 is still alive, then thread t1 transits to
the Blocked-for-join-completion state.
• Below is a program showing how threads invoke the overloaded thread join method.
public class ThreadJoinDemo
{
public static void main(String[] args)
{
Thread t1 = new Thread("T1");
Thread t2 = new Thread("T2");
try
{
System.out.println("Wait for the child threads to finish.");
t1.join();
if (!t1.isAlive())
{
System.out.println("Thread T1 is not alive.");
}
t2.join();
20
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
if (!t2.isAlive())
{
System.out.println("Thread T2 is not alive.");
}
}
catch (InterruptedException e)
Output
{
Wait for the child threads to finish.
System.out.println("Main Thread interrupted.");
Thread T1 is not alive.
}
Thread T2 is not alive.
System.out.println("Exit from Main Thread.");
Exit from Main Thread
}
}
21
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD STATES
A Java thread is always in one of several states which could be running, sleeping, dead, etc.
• A thread can be in any of the following states:
New Thread state (Ready-to-run state)
Runnable state (Running state)
Not Runnable state
Dead state
NEW THREAD
A thread is in this state when the instantiation of a Thread object creates a new thread but does not
start it running. A thread starts life in the Ready-to-run state. You can call only the start() or stop()
methods when the thread is in this state. Calling any method besides start() or stop() causes an
IllegalThreadStateException.
RUNNABLE
When the start() method is invoked on a New Thread() it gets to the runnable state or running state by
calling the run() method. A Runnable thread may actually be running, or may be awaiting its turn to run.
NOT RUNNABLE
A thread becomes Not Runnable when one of the following four events occurs:
When sleep() method is invoked and it sleeps for a specified amount of time
When suspend() method is invoked
When the wait() method is invoked and the thread waits for notification of a free resource or waits for
the completion of another thread or waits to acquire a lock of an object.
• The thread is blocking on I/O and waits for its completion
• Example: Thread.currentThread().sleep(1000);
• Note: Thread.currentThread() may return an output like Thread[threadA,5,main]
• The SleepMessages example uses sleep to print messages at four-second intervals:
22
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
DEAD STATE
A thread enters this state when the run() method has finished executing or when the stop() method is
invoked. Once in this state, the thread cannot ever run again.
23
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD CLASS
The Thread class defines a number of methods useful for thread management. These
include static methods, which provide information about, or affect the status of, the thread invoking
the method. The other methods are invoked from other threads involved in managing the thread
and Thread object.
The Thread class defines a number of methods useful for thread management. These
include static methods, which provide information about, or affect the status of, the thread invoking
the method. The other methods are invoked from other threads involved in managing the thread
and Thread object.
Pausing Execution with Sleep
Thread.sleep causes the current thread to suspend execution for a specified period. This is an efficient means
of making processor time available to the other threads of an application or other applications that might be
running on a computer system. The sleep method can also be used for pacing, as shown in the example that
follows, and waiting for another thread with duties that are understood to have time requirements.
24
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
INTERRUPTS
Thread interruption in java is a mechanism in which a thread which is either sleeping or waiting can be made
to stop sleeping or waiting. Thread interruption is like telling the thread that it should stop waiting or sleeping
and return to running status. Thread interruption is programmatically implemented usinginterrupt() method
of java.lang.Thread class. interrupt() method is a non-static public method of Thread class. Here is the method
signature of interrupt() method.
If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked), calling the interrupt() method on
the thread, breaks out the sleeping or waiting state throwing InterruptedException. If the thread is not in the
sleeping or waiting state, calling the interrupt() method performs normal behaviour and doesn't interrupt the
thread but sets the interrupt flag to true. Let's first see the methods provided by the Thread class for thread
interruption.
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up
to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the
thread to terminate. This is the usage emphasized in this lesson.
A thread sends an interrupt by invoking interrupt on the Thread object for the thread to be interrupted.
For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption.
The 3 methods provided by the Thread class for interrupting a thread
• public void interrupt()
• public static boolean interrupted()
• public boolean isInterrupted()
Example of interrupting a thread that stops working
• In this example, after interrupting the thread, we are propagating it, so it will stop working. If we don't
want to stop the thread, we can handle it where sleep() or wait() method is invoked. Let's first see the
example where we are propagating the exception.
class TestInterruptingThread1 extends Thread
{
public void run()
{
try
{
Thread.sleep(1000);
System.out.println("task");
}
catch(InterruptedException e)
{
throw new RuntimeException("Thread interrupted..."+e);
}
}
25
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
TestInterruptingThread1 t1=new TestInterruptingThread1();
t1.start();
try Output:
{ Exception in thread-0
t1.interrupt(); java.lang.RuntimeException: Thread interrupted...
} java.lang.InterruptedException: sleep interrupted
catch(Exception e) at A.run(A.java:7)
{
System.out.println("Exception handled "+e);
}
}
}
Here is an example for interrupting a sleeping thread using interrupt()
method.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = new Thread()
{
public void run()
{
try
{
Thread.sleep(10000); //Thread is sleeping for 10 seconds
}
catch (InterruptedException e)
{
System.out.println("Thread is interrupted");
}
}
}
t.start();
try
{
Thread.sleep(3000); //Main thread is sleeping for 3 seconds
}
catch (InterruptedException e)
{
e.printStackTrace();
}
t.interrupt(); //main thread is interrupting thread t
}
}
EXPLAIN:-
26
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
In the above example, main thread is creating and starting thread t. Thread t is going to sleep for 10 seconds
as soon as it started. main thread, after starting thread t, is also going to sleep for 3 seconds. After sleeping for
3 seconds, main thread calls interrupt() method on thread t. It interrupts sleeping thread t. It causes the
InterruptedException.
Example of interrupting a thread that doesn't stop working
• In this example, after interrupting the thread, we handle the exception, so it will break out the
sleeping but will not stop working.
class TestInterruptingThread2 extends Thread
{
public void run()
{
try
{
Output:
Thread.sleep(1000);
Exception handled
System.out.println("task");
java.lang.InterruptedException: sleep interrupted
}
thread is running...
catch(InterruptedException e)
{
System.out.println("Exception handled "+e);
}
System.out.println("thread is running...");
}
public static void main(String args[])
{
TestInterruptingThread2 t1=new TestInterruptingThread2();
t1.start();
t1.interrupt();
}
}
Example of interrupting thread that behaves normally
If thread is not in sleeping or waiting state, calling the interrupt() method sets the interrupted flag to true that
can be used to stop the thread by the java programmer.
class TestInterruptingThread3 extends Thread{
public void run()
{
for(int i=1;i<=5;i++)
{ Output:
System.out.println(i); 1
} 2
} 3
public static void main(String args[]) 4
{ 5
TestInterruptingThread3 t1=new TestInterruptingThread3();
t1.start();
t1.interrupt();
} }
27
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
try
{
Thread.sleep(10000); //Thread is going to sleep for 10 seconds
}
catch (InterruptedException e)
{
System.out.println("Thread is interrupted");
}
28
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
current interrupt status of a thread like isInterrupted() method. But, it clears interrupt
status of a thread. i.e if interrupt status of a thread is true, then it will set the status to
false.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = new Thread()
{
public void run()
{
System.out.println(interrupted()); //Output : false
interrupt();
System.out.println(interrupted()); //Output : true
System.out.println(interrupted()); //Output : false
}
}
t.start();
}
}
NOTE:-interrupt() method will throw SecurityException if current thread can not interrupt a calling thread.
A thread can interrupt itself. i.e a thread can call interrupt() method on it’s own.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = new Thread()
{
public void run()
{
System.out.println(isInterrupted()); //Output : false
interrupt(); //Thread interrupting itself
System.out.println(isInterrupted()); //Output : true
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.println("Thread interrupted");
}
System.out.println(isInterrupted()); //Output : false
}
}
t.start();
} }
Supporting Interruption
30
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
• The interrupt mechanism is implemented using an internal flag known as the interrupt status.
Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static
method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is
used by one thread to query the interrupt status of another, does not change the interrupt status flag.
• By convention, any method that exits by throwing an InterruptedException clears interrupt status
when it does so. However, it's always possible that interrupt status will immediately be set again, by
another thread invoking interrupt.
• The join method allows one thread to wait for the completion of another. If t is a Thread object whose
thread is currently executing, t.join(); causes the current thread to pause execution until t's thread
terminates. Overloads of join allow the programmer to specify a waiting period. However, as
with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly
as long as you specify.Like sleep, join responds to an interrupt by exiting with an InterruptedException.
• The whole thread interruption mechanism depends on an internal flag called interrupt status. The
initial value of this flag for any thread is false. When you call interrupt() method on a thread, interrupt
status of that thread will be set to true. When a thread throws InterruptedException, this status will be
set to false again. Remember, InterruptedException is thrown when a thread is interrupted while it is
sleeping or waiting. Many methods of Thread class like sleep(), wait(), join() throw
InterruptedException.
PAUSING EXECUTION WITH SLEEP
Thread.sleep causes the current thread to suspend execution for a specified period. This is an efficient means
of making processor time available to the other threads of an application or other applications that might be
running on a computer system. The sleep method can also be used for pacing, as shown in the example that
follows, and waiting for another thread with duties that are understood to have time requirements.
Two overloaded versions of sleep are provided: one that specifies the sleep time to the millisecond and one
that specifies the sleep time to the nanosecond. However, these sleep times are not guaranteed to be precise,
because they are limited by the facilities provided by the underlying OS. Also, the sleep period can be
terminated by interrupts.
In any case, you cannot assume that invoking sleep will suspend the thread for
precisely the time period specified Thread Methods:
• FOLLOWING IS THE LIST OF IMPORTANT METHODS AVAILABLE IN THE THREAD CLASS.
32
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
public void run():If this Thread object was instantiated using a separate Runnable
target, the run() method is invoked on that Runnable object, so,it is used to perform
action for a thread.
public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.
public static void sleep(long millisec):Causes the currently running thread to block
for at least the specified number of milliseconds.
public void yield(): causes the currently executing thread object to temporarily
pause and allow other threads to execute.
public static void yield():Causes the currently running thread to yield to any other
threads of the same priority that are waiting to be scheduled.
public final void join(long millisec):The current thread invokes this method on a
second thread, causing the current thread to block until the second thread
terminates or the specified number of milliseconds passes.
public final void setName(String name):Changes the name of the Thread object.
There is also a getName() method for retrieving the name.
public final void setPriority(int priority):Sets the priority of this Thread object. The
possible values are between 1 and 10.
public final void setDaemon(boolean on):A parameter of true denotes this Thread
as a daemon thread.
33
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
public final boolean isAlive()/public boolean isAlive(): Returns true if the thread is
alive, which is any time after the thread has been started but before it runs to
completion and so used for tests if the thread is alive.
public void setDaemon(boolean b): marks the thread as daemon or user thread.
public static boolean holdsLock(Object x):Returns true if the current thread holds
the lock on the given Object.
public static void dumpStack():Prints the stack trace for the currently running
thread, which is useful when debugging a multithreaded application.
34
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
public static Thread currentThread(): returns the reference of currently running thread.
• Example of currentThread() method:
class TestMultiNaming2 extends Thread
{
public void run()
{
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String args[])
{
TestMultiNaming2 t1=new TestMultiNaming2();
TestMultiNaming2 t2=new TestMultiNaming2();
t1.start();
t2.start();
}
}
Output:
Thread-0
Thread-1
So, thread class provide constructors and methods to create and perform operations on a thread.
Thread class extends Object class and implements Runnable interface.
Commonly used methods of Thread class:
public static boolean interrupted(): tests if the current thread has been interrupted.
• Runnable interface:The Runnable interface should be implemented by any class whose instances are
intended to be executed by a thread. Runnable interface have only one method named run().
• public void run(): is used to perform action for a thread.
• Who makes your class object as thread object?
Thread class constructor allocates a new thread object.When you create object of Multi class,your class
constructor is invoked(provided by Compiler) fromwhere Thread class constructor is invoked(by super() as first
statement).
35
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING
TERMINATED.
• java.lang.Thread class has one member of enum type called State.
• All states of a thread are stored in this enum as constants.
EXECUTE THE BELOW PROGRAM, IT PRINTS ALL STATES OF A THREAD.
public class ThreadsInJava
{ The output of this program will be,
public static void main(String[] args) NEW
{ RUNNABLE
Thread.State[] states = Thread.State.values(); BLOCKED
WAITING
for (Thread.State state : states) TIMED_WAITING
{ TERMINATED
System.out.println(state);
}
}
}
36
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
37
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
BELOW DIAGRAM CLEARLY DEPICTS THE VARIOUS PHASES OF THREAD LIFE CYCLE IN JAVA.
1) NEW
A thread will be in this state before calling start() method.
public class JavaThreadLifeCycle
{
public static void main(String[] args)
{
Thread t = new Thread();
//Checking the state before starting the thread
System.out.println(t.getState()); //Output : NEW
}
}
2) RUNNABLE
A thread will be in this state after calling the start() method.
public class JavaThreadLifeCycle
{
public static void main(String[] args)
{
Thread t = new Thread();
t.start();
//Checking the state after starting the thread
System.out.println(t.getState()); //Output : RUNNABLE
}
}
3) BLOCKED
38
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
A thread will be in this state when a thread is waiting for object lock to enter into synchronized
method/block or a thread will be in this state if deadlock occurs.
• Below example shows the states of two threads when deadlock occurs.
class Shared
{
synchronized void methodOne(Shared s)
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
s.methodTwo(this);
}
synchronized void methodTwo(Shared s)
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
s.methodOne(this);
}
}
public class ThreadsInJava
{
public static void main(String[] args)
{
final Shared s1 = new Shared();
final Shared s2 = new Shared();
Thread t1 = new Thread()
{
public void run()
{
s1.methodOne(s2);
}
}
39
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
public void run()
{
s2.methodTwo(s1);
}
}
t1.start();
t2.start();
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//Checking states of both the threads
System.out.println(t1.getState()); //Output : BLOCKED
System.out.println(t2.getState()); //Output : BLOCKED
}
}
4) WAITING
A thread will be in this state when wait() or join() method is called. Below example shows the thread state
when join() method is called.
public class ThreadsInJava
{
public static void main(String[] args)
{
final Thread t1 = new Thread()
{
public void run()
{
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
t.start();
try
41
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//Checking the state when thread is sleeping
System.out.println(t.getState()); //Output : TIMED_WAITING
}
}
6) TERMINATED
A thread will be in this state once it finishes it’s execution.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = new Thread()
{
public void run()
{
for(int i = 0; i <= 25; i++)
{
System.out.println(i);
} } };
t.start();
try
{
Thread.sleep(2000); //Main thread is sleeping for 2 sec
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//Checking the state when thread t is finished it's execution
System.out.println(t.getState()); //Output : TERMINATED
}
}
42
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
43
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD SCHEDULER
The thread scheduler, part of the OS (usually) that is responsible for sharing the available CPUs out between
the various threads. How exactly the scheduler works depends on the individual platform, but various modern
operating systems (notably Windows and Linux) use largely similar techniques .
Again, the thread scheduler is the part of the JVM that decides which thread should run at any given
moment, and also takes threads out of the run state. Any thread in the runnable state can be chosen by the
scheduler to be the one and only running thread. If a thread is not in a runnable state, then it cannot be
chosen to be the currently running thread. Some method that can influence scheduler to some extent(Note*:
We can’t control the behavior of Thread scheduler).
Schedulers in JVM implementations usually employ one of the two following
strategies:
• Preemptive scheduling
If a thread with a higher priority than all other Runnable threads becomes Runnable, the scheduler will
preempt the running thread (is moved to the runnable state) and choose the new higher priority thread for
execution.
• Time-Slicing or Round-Robin scheduling
A running thread is allowed to execute for a fixed length of time (a time slot it’s assigned to), after
which it moves to the Ready-to-run state (runnable) to await its turn to run again.
A thread scheduler is implementation and platform-dependent; therefore, how threads will be
scheduled is unpredictable across different platforms.
NOTE:-
• On multiprocessor systems, there is generally some kind of scheduler per processor, which then need
to be coordinated in some way. (On some systems, switching on different processors is staggered to
avoid contention on shared scheduling tables.) Unless otherwise specified, we'll use the term thread
scheduler to refer to this overall system of coordinated per-CPU schedulers.
• Thread scheduler in java is the part of the JVM that decides which thread should run.
• There is no guarantee that which runnable thread will be chosen to run by the thread scheduler.
• Only one thread at a time can run in a single process.
• The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads.
44
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Most systems use what might dub priority-based round-robin scheduling to some
extent. The general principles are:
• a thread of higher priority (which is a function of base and local priorities) will preempt a thread of
lower priority;
• otherwise, threads of equal priority will essentially take turns at getting an allocated slice
or quantum of CPU;
• there are a few extra "tweaks" to make things work.
STATES
Depending on the system, there are various states that a thread can be in. Probably the two most
interesting are:
• runnable, which essentially means "ready to consume CPU"; being runnable is generally
the minimum requirement for a thread to actually be scheduled on to a CPU;
• waiting, meaning that the thread currently cannot continue as it is waiting for a resource such as a lock
or I/O, for memory to be paged in, for a signal from another thread, or simply for a period of time to
elapse (sleep).
45
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
EXAMPLE:-
class TestCallRun2 extends Thread Output:
{ 1
public void run() 2
{ 3
for(int i=1;i<5;i++) 4
{ 5
try 1
{ 2
Thread.sleep(500); 3
} 4
catch(InterruptedException e) 5
{
System.out.println(e);
}
System.out.println(i);
}
}
public static void main(String args[])
{
TestCallRun2 t1=new TestCallRun2();
TestCallRun2 t2=new TestCallRun2();
t1.run();
t2.run();
}
}
47
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
TYPES OF SCHEDULING
• Waiting and Notifying
Waiting [wait()] and notifying [notify(), notifyAll()] provides means of communication between threads that
synchronize on the same object.
• wait(): when wait() method is invoked on an object, the thread executing that code gives up its lock
on the object immediately and moves the thread to the wait state.
• notify(): This wakes up threads that called wait() on the same object and moves the thread to ready
state.
• notifyAll(): This wakes up all the threads that called wait() on the same object.
48
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
50
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
51
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
52
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
53
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
//Thread t4 will notify only one thread which is waiting for lock of object 's'
Thread t4 = new Thread()
{ Output :
public void run() Thread-1 is releasing the lock and going to wait
{ Thread-0 is releasing the lock and going to wait
s.notifyOneThread(); Thread-2 is releasing the lock and going to wait
} Thread-3 has notified one thread waiting for this object lock
} Thread-1 has been notified and acquired the lock back
t4.start();
}
}
notifyAll() In Java :
When a thread calls notifyAll() method on a particular object, all threads which are waiting for the lock of that
object are notified. All notified threads will move from WAITING state to BLOCKED state. All these threads will
get the lock of the object on a priority basis. The thread which gets the lock of the object moves to RUNNING
state. The remaining threads will remain in BLOCKED state until they get the object lock.
• Below is an example of notifyAll() method in Java.
class Shared
{
synchronized void waitMethod()
{
Thread t = Thread.currentThread();
System.out.println(t.getName()+" is releasing the lock and going to wait");
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(t.getName()+" has been notified and acquired the lock back");
}
synchronized void notifyAllThread()
{
Thread t = Thread.currentThread();
notifyAll();
System.out.println(t.getName()+" has notified all threads waiting for this object lock");
}
}
public class MainClass
{
public static void main(String[] args)
{
final Shared s = new Shared();
//Thread t1 will be waiting for lock of object 's'
54
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
55
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
56
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
wait() sleep()
The thread which calls wait() method The thread which calls sleep() method
releases the lock it holds. doesn’t release the lock it holds.
wait() method must be called within the sleep() method can be called within
synchronized block. or outside the synchronized block.
wait() method is always called on objects. sleep() method is always called on threads.
wait() is a non-static method of Object class. sleep() is a static method of Thread class.
Waiting threads can be awake by other Sleeping threads can not be awake by other
threads by calling notify() or notifyAll() threads. If done so, thread will throw
methods. InterruptedException.
To call wait() method, thread must have To call sleep() method, thread need not to
object lock. have object lock.
57
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
58
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD PRIORITIES:
Every Java thread has a priority that helps the operating system determine the order in which threads
are scheduled.
Java thread priorities are in the range between MIN_PRIORITY (a constant of 1) and MAX_PRIORITY
(a constant of 10). By default, every thread is given priority NORM_PRIORITY (a constant of 5). The
higher the integer, the higher the priority. Normally the thread priority will be 5.
Threads with higher priority are more important to a program and should be allocated processor time
before lower-priority threads. However, thread priorities cannot guarantee the order in which threads
execute and very much platform dependent.
Thread priorities are the integers which decide how one thread should be treated with respect to the
others.
Thread priority decides when to switch from one running thread to another, process is called context
switching
A thread can voluntarily release control and the highest priority thread that is ready to run is given the
CPU.
A thread can be preempted by a higher priority thread no matter what the lower priority thread is
doing. Whenever a higher priority thread wants to run it does.
To set the priority of the thread setPriority() method is used which is a method of the
class Thread Class.
In place of defining the priority in integers, we can
useMIN_PRIORITY, NORM_PRIORITY or MAX_PRIORITY.
59
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Synchronization of Threads
In many cases concurrently running threads share data and two threads try to do operations on the
same variables at the same time. This often results in corrupt data as two threads try to operate on the
same data.
A popular solution is to provide some kind of lock primitive. Only one thread can acquire a particular
lock at any particular time. This can be achieved by using a keyword “synchronized” .
By using the synchronize only one thread can access the method at a time and a second call will be
blocked until the first call returns or wait() is called inside the synchronized method.
Each thread have a priority. Priorities are represented by a number between 1 and 10. In most cases,
thread schedular schedules the threads according to their priority (known as preemptive scheduling).
But it is not guaranteed because it depends on JVM specification that which scheduling it chooses.
• 3 constants defiend in Thread class:
public static int MIN_PRIORITY
public static int NORM_PRIORITY
public static int MAX_PRIORITY
Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the
value of MAX_PRIORITY is 10.
• Example of priority of a Thread:
class TestMultiPriority1 extends Thread
{
public void run()
{
System.out.println("running thread name is:"+Thread.currentThread().getName());
System.out.println("running thread priority is:"+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:
running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1
60
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
61
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
2) Daemon Thread
• Daemon thread in java is a service provider thread that provides services to the user thread. Its life
depend on the mercy of user threads i.e. when all the user threads dies, JVM terminates this thread
automatically.
• There are many java daemon threads running automatically e.g. gc, finalizer etc.
Points to remember for Daemon Thread in Java
• It provides services to user threads for background supporting tasks. It has no role in life than to serve
user threads.
• Its life depends on user threads.
• It is a low priority thread.
62
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Java makes a distinction between a user thread and another type of thread known as
a daemon thread.
The daemon threads are typically used to perform services for user threads. The main() method of the
application thread is a user thread. Threads created by a user thread are user thread. JVM doesn't
terminates unless all the user thread terminate.
User can explicitly specify a thread created by a user thread to be a daemon thread by calling
setDaemon(true) on a Thread object. For example, the clock handler thread, the idle thread, the
garbage collector thread, the screen updater thread, and the garbage collector thread are all daemon
threads. A new created thread inherits the "daemon-status" of the thread that created it unless you
explicitly calling setDaemon on that Thread object to change its status.
the setDaemon() method must be called before the thread's start() method is invoked.Once a thread
has started executing (i.e., its start() method has been called) its daemon status cannot be changed. To
determine if a thread is a daemon thread, use the accessor method isDaemon().
whether the thread is user thread or a daemon thread by using isDaemon() method of
Thread class. This method returns “true” for a daemon thread and “false” for a user
thread.
63
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
public void setDaemon(boolean is used to mark the current thread as daemon thread or
status) user thread.
public boolean isDaemon() is used to check that current is daemon.
To make a user thread as Daemon, it must not be started otherwise it will throw
illegalthreadstateexception.
• File: MyThread.java
class TestDaemonThread2 extends Thread
{
public void run()
66
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
System.out.println("Name: "+Thread.currentThread().getName());
System.out.println("Daemon: "+Thread.currentThread().isDaemon());
}
public static void main(String[] args)
{
TestDaemonThread2 t1=new TestDaemonThread2();
TestDaemonThread2 t2=new TestDaemonThread2();
t1.start();
t1.setDaemon(true);//will throw exception here
t2.start();
}
}
Output: exception in thread main: java.lang.IllegalThreadStateException
Example:
public class CrunchifyDaemonThread extends Thread
{
public static void main(String[] args)
{
System.out.println("Main Method Entry");
CrunchifyDaemonThread t = new CrunchifyDaemonThread();
t.setDaemon(true);
// When false, (i.e. when it's a user thread), the Worker thread
// continues to run.
// When true, (i.e. when it's a daemon thread), the Worker thread
// terminates when the main thread terminates.
t.start();
try
{
Thread.sleep(3000);
}
catch (InterruptedException x)
{}
System.out.println("Main Method Exit");
}
public void run()
{
System.out.println("run Method Entry");
try
{
System.out.println("In run Method: currentThread() is"+ Thread.currentThread());
while (true)
{
try
{
Thread.sleep(1000);
}
67
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
catch (InterruptedException x)
{ }
System.out.println("In run method.." + Thread.currentThread());
}
}
finally
{
System.out.println("run Method Exit");
}
}
}
Output1: (with t.setDaemon(true)):
with t.setDaemon(true);
Main Method Entry
run Method Entry
In run Method: currentThread() isThread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
Main Method Exit
Output2: (with t.setDaemon(false)):
with t.setDaemon(false);
Main Method Entry
run Method Entry
In run Method: currentThread() isThread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
Main Method Exit
In run method..Thread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
In run method..Thread[Thread-0,5,main]
...
...
...
EXAMPLE:-
public class DaemonThreadExample
{
public static void main(String args[])
{
Thread daemonThread = new Thread(new Runnable()
68
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
public void run()
{
try
{
while(true)
{
System.out.println("Daemon thread is running");
}
}
catch(Exception e)
{ }
Finally
{
System.out.println("Daemon Thread exiting"); //never called
}
}
}
daemonThread.setDaemon(true); //making this thread daemon
daemonThread.start();
}
Output:
Daemon thread is running
Daemon thread is running
Daemon thread is running
Daemon thread is running
Daemon thread is running
Daemon thread is running
Daemon thread is running
Daemon thread is running
JVM waits for user threads to finish their JVM will not wait for daemon threads to
work. It will not exit until all user threads finish their work. It will exit as soon as all user
finish their work. threads finish their work.
User threads are mainly designed to do some Daemon threads are designed to support the
specific task. The application is very much user threads. The application is less
dependent on the user threads for it’s dependent on the daemon threads for it’s
smooth execution. smooth running.
JVM will not force the user threads to JVM will force the daemon threads to
terminate. It will wait for user threads to terminate if all user threads have finished
terminate themselves. their work.
70
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD POOLING
Pooling is usually implemented by loop i.e to check some condition repeatedly. Once condition is true
appropriate action is taken. This waste CPU time.
Java Thread pool represents a group of worker threads that are waiting for the job and reuse many
times.
In case of thread pool, a group of fixed size threads are created. A thread from the thread pool is pulled
out and assigned a job by the service provider. After completion of the job, thread is contained in the thread
pool again.
Advantage of Java Thread Pool
Better performance It saves time because there is no need to create new thread.
71
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
File: JavaThreadPoolExample.java
public class TestThreadPool
{
public static void main(String[] args)
{
ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads
for (int i = 0; i < 10; i++)
{
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);//calling execute method of ExecutorService
}
executor.shutdown();
while (!executor.isTerminated()) { }
System.out.println("Finished all threads");
}
}
Output:
pool-1-thread-1 (Start) message = 0
pool-1-thread-2 (Start) message = 1
pool-1-thread-3 (Start) message = 2
pool-1-thread-5 (Start) message = 4
pool-1-thread-4 (Start) message = 3
pool-1-thread-2 (End)
pool-1-thread-2 (Start) message = 5
pool-1-thread-1 (End)
pool-1-thread-1 (Start) message = 6
pool-1-thread-3 (End)
pool-1-thread-3 (Start) message = 7
pool-1-thread-4 (End)
pool-1-thread-4 (Start) message = 8
pool-1-thread-5 (End)
pool-1-thread-5 (Start) message = 9
pool-1-thread-2 (End)
pool-1-thread-1 (End)
pool-1-thread-4 (End)
pool-1-thread-3 (End)
pool-1-thread-5 (End)
Finished all threads
72
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
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.
73
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
74
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Example Program 2:
• Observe the output of this program and try to understand what is happening in this program.
If you have understood the usage of each thread method then you would not face any issue,
understanding this example.
class Count implements Runnable
{
Thread mythread ;
Count()
{
mythread = new Thread(this, "my runnable thread");
System.out.println("my thread created" + mythread);
mythread.start();
}
public void run()
{
Output:
try my thread createdThread[my runnable thread,5,main]
{ Main thread will be alive till the child thread is live
for (int i=0 ;i<10;i++) Printing the count 0
{ Printing the count 1
System.out.println("Printing the count " + i); Main thread will be alive till the child thread is live
Printing the count 2
Thread.sleep(1000); Main thread will be alive till the child thread is live
} Printing the count 3
} Printing the count 4
catch(InterruptedException e) Main thread will be alive till the child thread is live
{ Printing the count 5
Main thread will be alive till the child thread is live
System.out.println("my thread interrupted"); Printing the count 6
} Printing the count 7
System.out.println("mythread run is over" ); Main thread will be alive till the child thread is live
} Printing the count 8
} Main thread will be alive till the child thread is live
Printing the count 9
class RunnableExample mythread run is over
{ Main thread run is over
public static void main(String args[])
{
Count cnt = new Count();
try
{
while(cnt.mythread.isAlive())
{
System.out.println("Main thread will be alive till the child thread is live");
Thread.sleep(1500);
}
}
catch(InterruptedException e)
{
System.out.println("Main thread interrupted");
}
System.out.println("Main thread run is over" ); } }
75
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
76
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
class ExtendingExample
{
public static void main(String args[])
{
Count cnt = new Count();
try
{
while(cnt.isAlive())
{
System.out.println("Main thread will be alive till the child thread is live");
Thread.sleep(1500);
}
}
catch(InterruptedException e)
{
System.out.println("Main thread interrupted");
}
System.out.println("Main thread's run is over" );
}
}
77
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
DEADLOCK IN JAVA
Whenever there is multiple processes contending for exclusive access to multiple locks, there is the possibility
of deadlock. A set of processes or threads is said to be deadlocked when each is waiting for an action that only
one of the others can perform.
In Order to avoid deadlock, one should ensure that when you acquire multiple locks, you always
acquire the locks in the same order in all threads.
There are situations when programs become deadlocked when each thread is waiting on a resource
that cannot become available. The simplest form of deadlock is when two threads are each waiting on a
resource that is locked by the other thread. Since each thread is waiting for the other thread to relinquish a
lock, they both remain waiting forever in the Blocked-for-lock-acquisition state. The threads are said to be
deadlocked.
Thread t1 at tries to synchronize first on string s1 and then on string s2. The thread t2 does the opposite. It
synchronizes first on string s2 then on string s1.
78
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
NOTE:-Deadlock is a situation of complete Lock, when no thread can complete its execution because lack of
resources. In the above picture, Thread 1 is holding a resource R1, and need another resource R2 to finish
execution, but R2 is locked by Thread 2, which needs R3, which in turn is locked by Thread 3. Hence none of
them can finish and are stuck in a deadlock.
Example of deadlock
class Pen{ }
class Paper{ }
public class Write
{
public static void main(String[] args)
{
final Pen pn =new Pen();
final Paper pr =new Paper();
Thread t1 = new Thread(){
public void run()
{
synchronized(pn)
{
System.out.println("Thread1 is holding Pen");
try
{
Thread.sleep(1000);
}
catch(InterruptedException e){}
synchronized(pr)
{
System.out.println("Requesting for Paper");
}
}
}
}
79
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
synchronized (resource2)
{
System.out.println("Thread 1: locked resource 2");
}
}
}
}
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread()
{
public void run()
{
synchronized (resource2)
{
System.out.println("Thread 2: locked resource 2");
try
{
Thread.sleep(100);
}
catch (Exception e) { }
synchronized (resource1)
{
System.out.println("Thread 2: locked resource 1");
}
}
}
}
t1.start();
t2.start();
}
}
Output:
Thread 1: locked resource 1
Thread 2: locked resource 2
81
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
EXPLANATION:-
82
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
• In the above multithreaded program, thread t1 and t2 are concurrent threads i.e they are executing
their task simultaneously. There are two Shared class objects, s1 and s2, which are shared by both the
threads. Shared class has two synchronized methods, methodOne() and methodTwo(). That means,
only one thread can execute these methods at a given time.
• First, thread t1 enters the methodOne() of s1 object by acquiring the object lock of s1. At the same
time, thread t2 also enters the methodTwo() of s2 object by acquiring the object lock
of s2. methodOne() of s1object, currently executing by thread t1, calls methodTwo() of s2 object from
it’s body. So, thead t1 tries to acquire the object lock of s2 object. But object lock of s2 object is already
acquired by thread t2. So, threadt1 waits for thread t2 to release the object lock of s2 object.
• At the same time, thread t2 is also executing methodTwo() of s2 object. methodTwo() of s2 object also
makes a call to methodOne() of s1 object. So, thread t2 tries to acquire the object lock of s1 object.
But, it is already acquired by thread t1. So, thread t2 also waits for thread t1 to release the object lock
of s1 object.
• Thus, both the threads wait for each other to release the object locks they own. They wait for infinite
period of time to get the object locks owned by opposite threads. This condition of threads waiting
forever is called Deadlock.
83
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
84
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Here are the some methods of ThreadInfo class which are useful to retrieve the details
of deadlocked threads.
getThreadId() —> Returns the ID of a deadlocked thread.
getThreadName() —> Returns the name of a deadlocked thread.
getBlockedTime() —> Returns the elapsed time in milli seconds that a thread is in deadlock
condition.
getLockName() —> Returns string representation of an object for which thread has been
waiting.
getLockOwnerId() —> Returns ID of a thread that currently owns the object lock.
getLockOwnerName() —> Returns the name of a thread that currently owns the object lock.
86
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Example that has been modified to get the details of deadlocked threads.
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
class Shared
{
synchronized void methodOne(Shared s)
{
Thread t = Thread.currentThread();
System.out.println(t.getName()+"is executing methodOne...");
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(t.getName()+"is calling methodTwo...");
s.methodTwo(this);
System.out.println(t.getName()+"is finished executing methodOne...");
}
synchronized void methodTwo(Shared s)
{
Thread t = Thread.currentThread();
System.out.println(t.getName()+"is executing methodTwo...");
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(t.getName()+"is calling methodOne...");
s.methodOne(this);
System.out.println(t.getName()+"is finished executing methodTwo...");
}
}
public class ThreadsInJava
{
public static void main(String[] args)
{
final Shared s1 = new Shared();
final Shared s2 = new Shared();
Thread t1 = new Thread()
{
public void run()
{
s1.methodOne(s2);
}
}
87
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
88
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
INTERTHREAD COMMUNICATION
Threads can communicate with each other using wait(), notify() and notifyAll() methods. These methods are
final methods of java.lang.Object class. That means every class in java will have these methods. All these
methods can only be called from within a synchronized method.
1) To understand synchronization java has a concept of monitor. Monitor can be thought of as a box which
can hold only one thread. Once a thread enters the monitor all the other threads have to wait until that thread
exits the monitor.
2) wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the
same monitor and calls notify().
3) notify() wakes up the first thread that called wait() on the same object.notifyAll() wakes up all the threads
that called wait() on the same object. The highest priority thread will run first.
1) wait() method
Causes current thread to release the lock and wait until either another thread invokes the notify() method or
the notifyAll() method for this object, or a specified amount of time has elapsed.
The current thread must own this object's monitor, so it must be called from the synchronized method only
otherwise it will throw exception.
Method Description
public final void wait()throws InterruptedException waits until object is notified.
public final void wait(long timeout)throws waits for the specified amount of time.
InterruptedException
2) notify() method
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one
of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation.
Syntax:public final void notify()
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor.
Syntax:public final void notifyAll()
89
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Why wait(), notify() and notifyAll() methods are defined in Object class not Thread
class?
It is because they are related to lock and object has a lock.
wait() sleep()
wait() method releases the lock sleep() method doesn't release the lock.
is the method of Object class is the method of Thread class
is the non-static method is the static method
is the non-static method is the static method
should be notified by notify() or notifyAll() after the specified amount of time, sleep is
methods completed.
90
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
92
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Explanation:-
In this example, Thread t1 and t2 are sharing shared class object ‘s’. Thread t1 is calling methodOne() and
thread t2 is calling methodTwo() of ‘s’ object. Both the methods are synchronized. That means, for any thread
to enter these methods, they must acquire lock of ‘s’ object.
• First, thread t1 acquires the object lock and enters methodOne(). Thread t2 waits for thread t1 to
release the object lock. Thread t1 calls wait() method within methodOne(). As soon as, it calls wait()
method, It releases the lock of ‘s’ object and goes for wait. Thread t2 acquires this lock and enters
methodTwo(). After entering methodTwo(), thread t2 sleeps for 5 seconds and calls notify() method on
this object. It wakes up thread t1 which is waiting for this object lock. As soon as, thread t2 releases the
object lock after finishing it’s execution of methodTwo(), thread t1 acquires this lock and executes
remaining statements of methodOne(). In this manner, both threads t1 and t2 communicate with each
other and share the lock.
93
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
94
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
95
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
METHOD DESCRIPTION
int activeCount() returns no. of threads running in current group.
int activeGroupCount() returns a no. of active group in this thread group.
void destroy() destroys this thread group and all its sub groups.
String getName() returns the name of this group.
ThreadGroup getParent() returns the parent of this group.
void interrupt() interrupts all threads of this group.
void list() prints information of this group to standard console.
Now all 3 threads belong to one group. Here, tg1 is the thread group name, MyRunnable is the class
that implements Runnable interface and "one", "two" and "three" are the thread names.
96
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
98
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
99
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
100
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
t2.start();
ThreadGroup childGroup = new ThreadGroup(parentGroup, "Child Group");
Thread t3 = new Thread(childGroup, "Thread 3");
t3.start();
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//Destroying the whole group
parentGroup.destroy();
}
}
enumerate() Method :
There exist four versions of enumerate() method in ThreadGroup class. They are,
1. public int enumerate(Thread[] list) —> It copies all active threads of a group into specified array of
threads.
2. public int enumerate(Thread[] list, boolean recurse) —> It copies all active threads of a group into
specified array of threads. If recurse is true, subgroups are also enumerated.
3. public int enumerate(ThreadGroup[] list) —> It copies all active subgroups of a thread group into
specified array of ThreadGroup.
4. public int enumerate(ThreadGroup[] list, boolean recurse) —> It copies all active subgroups of a
thread group into specified array of ThreadGroup. If recurse is true, subgroups of subgroups are also
enumerated.
public class ThreadsInJava
{
public static void main(String[] args)
{
//Creating Thread Group
ThreadGroup parentGroup = new ThreadGroup("Parent Group ");
Thread t1 = new Thread(parentGroup, "Thread 1")
{
public void run()
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} }
t1.start();
Thread t2 = new Thread(parentGroup, "Thread 2")
102
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
{
public void run()
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
t2.start();
ThreadGroup childGroup = new ThreadGroup(parentGroup, "Child Group");
Thread t3 = new Thread(childGroup, "Thread 3")
{
public void run()
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
t3.start();
//Enumerating all active threads
Thread[] threads = new Thread[parentGroup.activeCount()];
int No_Of_Active_Threads = parentGroup.enumerate(threads);
System.out.println(No_Of_Active_Threads);
for (Thread thread : threads)
{
System.out.println(thread.getName());
}
}
}
As all know that start() method internally calls run() method. What happens when you
call run() method directly?. When call run() method of a thread directly, calling thread
will execute the task defined in the run() method. For example, in the below
104
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
program main thread is calling run() method of thread t. In this case, main thread will
execute run() method not thread t.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = new Thread()
{
public void run()
{
System.out.println(Thread.currentThread().getName()); //Output : main
}
}
t.run();
}
}
Which one is better way to implement threads in java. Is it using Thread class or using
Runnable interface?.
It is the most confusing question for a java developer, of opinion that when multiple threads
need to execute same task, then use Runnable interface. If multiple threads need to execute
different tasks, then go for Thread class.
Setting the priority to a thread is not effective as we thought. Setting Priority of a thread is just an
advice to OS not an instruction. It is up to OS to consider this advice.
Every thread in java is a member of a thread group. When a java application first
starts up, Java runtime system creates a thread group called main. main thread is also
member of this group.
public class ThreadsInJava
{
public static void main(String[] args)
{
Thread t = Thread.currentThread();
System.out.println(t.getThreadGroup());
//Output : java.lang.ThreadGroup[name=main,maxpri=10]
}
}
105
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SHUTDOWN HOOK
The shutdown hook can be used to perform cleanup resource or save the state when JVM shuts down
normally or abruptly. Performing clean resource means closing log file, sending some alerts or something else.
So if you want to execute some code before JVM shuts down, use shutdown hook.
When does the JVM shut down?
• The JVM shuts down when:
user presses ctrl+c on the command prompt
System.exit(int) method is invoked
user logoff
user shutdown etc.
The addShutdownHook(Runnable r) method
The addShutdownHook() method of Runtime class is used to register the thread with the Virtual Machine.
Syntax: public void addShutdownHook(Runnable r){ }
The object of Runtime class can be obtained by calling the static factory method getRuntime().
For example:
Runtime r = Runtime.getRuntime();
Factory method
• The method that returns the instance of a class is known as factory method.
Simple example of Shutdown Hook
class MyThread extends Thread
{
public void run()
{
System.out.println("shut down hook task completed..");
}
}
public class TestShutdown1
{
public static void main(String[] args)throws Exception
{
Runtime r=Runtime.getRuntime();
r.addShutdownHook(new MyThread());
System.out.println("Now main sleeping... press ctrl+c to exit");
try
{
Thread.sleep(3000);
}
catch (Exception e) { }
Note: The shutdown sequence can be
} stopped by invoking the halt(int) method of
} Runtime class.
Output:
Now main sleeping... press ctrl+c to exit
shut down hook task completed..
106
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
107
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
108
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
109
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
110
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
111
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
113
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SYNCHRONIZATION IN JAVA
Multithreading introduces asynchronous behavior to the programs. If a thread is writing some data
another thread may be reading the same data at that time. This may bring inconsistency.
When two or more threads need access to a shared resource there should be some way that the
resource will be used only by one resource at a time. The process to achieve this is called
synchronization.
To implement the synchronous behavior java has synchronous method. Once a thread is inside a
synchronized method, no other thread can call any other synchronized method on the same object. All
the other threads then wait until the first thread come out of the synchronized block.
When want to synchronize access to objects of a class which was not designed for the multithreaded
access and the code of the method which needs to be accessed synchronously is not available with us,
in this case we cannot add the synchronized to the appropriate methods. In java we have the solution
for this, put the calls to the methods (which needs to be synchronized) defined by this class inside a
synchronized block in following manner.
Synchronized(object)
{
// statement to be synchronized
}
Synchronize: It works with Lock. Lock is of two type.
1. Static lock
2. Non static lock
Note: There is only one lock per object. Once a thread got the lock of an object no other
thread can enter the synchronise block/method of given object.
Only methods/block can be synchronised not variable or class.
A class can have both synchronised / non synchronised method.
Thread can access non synchronised block even if one Thread got the lock of give object.
If a thread goes to sleep, it holds any locks it has. A thread can have Lock of different object at the
same time.
Syntax :
class SyncTest
{
public void doStuff()
{
System.out.println("not synchronized");
synchronized(this)
{
System.out.println("synchroni
zed");
}
}
}
114
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
115
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Grouping of threads
Thread groups provide a mechanism for collecting multiple threads into a single object and manipulating those
threads all at once, rather than individually.
To put a new thread in a thread group the group must be explicitly specified when the thread is created
public Thread(ThreadGroup group, Runnable runnable)
public Thread(ThreadGroup group, String name)
public Thread(ThreadGroup group, Runnable runnable, String name)
A thread can not be moved to a new group after the thread has been created.
When a Java application first starts up, the Java runtime system creates a ThreadGroup named main.
Java thread groups are implemented by the java.lang.ThreadGroup class.
Synchronization
At times when more than one thread try to access a shared resource, we need to ensure that resource
will be used by only one thread at a time. The process by which this is achieved is
called synchronization. The synchronization keyword in java creates a block of code referred to as
critical section.
Every Java object with a critical section of code gets a lock associated with the object. To enter critical
section a thread need to obtain the corresponding object's lock.
General Syntax :
synchronized (object)
{
//statement to be synchronized
}
Why we use Syncronization ?
If we do not use syncronization, and let two or more threads access a shared resource at the same
time, it will lead to distorted results.
Consider an example, Suppose we have two different threads T1 and T2, T1 starts execution and save
certain values in a file temporary.txt which will be used to calculate some result when T1 returns.
Meanwhile, T2 starts and before T1 returns, T2 change the values saved by T1 in the file temporary.txt
(temporary.txt is the shared resource). Now obviously T1 will return wrong result.
To prevent such problems, synchronization was introduced. With synchronization in above case, once
T1 starts using temporary.txt file, this file will be locked(LOCK mode), and no other thread will be able
to access or modify it until T1 returns.
SO,
The synchronization is mainly used to
To prevent thread interference.
To prevent consistency problem.
116
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
EXPLANATION-
In the above program, object fnew of class First is shared by all the three running threads(ss, ss1 and
ss2) to call the shared method(void display). Hence the result is unsynchronized and such situation is
called Race condition.
Synchronization in java is the capability to control the access of multiple threads to any shared
resource.
Java Synchronization is better option where we want to allow only one thread to access the shared
resource.
117
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Types of Synchronization
There are two types of synchronization
1. Process Synchronization
2. Thread Synchronization
Thread Synchronization
There are two types of thread synchronization
1. mutual exclusive
2. inter-thread communication.
1. Mutual Exclusive
Synchronized method.
Synchronized block.
static synchronization.
Cooperation (Inter-thread communication in java)
So, Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be
done by three ways in java:
1. by synchronized method
2. by synchronized block
3. by static synchronization
Concept of Lock in Java
Synchronization is built around an internal entity known as the lock or monitor. Every object has an
lock associated with it. By convention, a thread that needs consistent access to an object's fields has to
acquire the object's lock before accessing them, and then release the lock when it's done with them.
From Java 5 the package java.util.concurrent.locks contains several lock implementations.
Understanding the problem without Synchronization
In this example, there is no synchronization, so output is inconsistent.
Class Table
{
void printTable(int n) //method not synchronized
{
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try
{
Thread.sleep(400);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
118
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
119
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
THREAD SYNCHRONIZATION
With respect to multithreading, Synchronization is a process of controlling the access of shared
resources by the multiple threads in such a manner that only one thread can access a particular
resource at a time.
In non synchronized multithreaded application, it is possible for one thread to modify a shared object
whileanother thread is in the process of using or updating the object’s value. Synchronization prevents
such typeof data corruption which may otherwise lead to dirty reads and significant errors.
Generally critical sections of the code are usually marked with synchronized keyword.
Examples of using Thread Synchronization is in “The Producer/Consumer Model”.
Locks are used to synchronize access to a shared resource. A lock can be associated with a shared resource.
Threads gain access to a shared resource by first acquiring the lock associated with the object/block of code.
At any given time, at most only one thread can hold the lock and thereby have access to the shared resource.
A lock thus implements mutual exclusion.
The object lock mechanism enforces the following rules of synchronization:
A thread must acquire the object lock associated with a shared resource, before it can enter the shared
resource. The runtime system ensures that no other thread can enter a shared resource if another
thread
already holds the object lock associated with the shared resource. If a thread cannot immediately
acquire
the object lock, it is blocked, that is, it must wait for the lock to become available.
When a thread exits a shared resource, the runtime system ensures that the object lock is also
relinquished.
If another thread is waiting for this object lock, it can proceed to acquire the lock in order to gain
access
to the shared resource.
Classes also have a class-specific lock that is analogous to the object lock. Such a lock is actually a
lock on the java.lang.Class object associated with the class. Given a class A, the reference A.class
denotes this unique Class object. The class lock can be used in much the same way as an object lock to
implement mutual exclusion.
120
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SYNCHRONIZED METHODS
PROERTIES:-
1. Synchronized methods are methods that are used to control access to an object.
2. A thread only executes a synchronized method after it has acquired the lock for the method’s object or
class. .If the lock is already held by another thread, the calling thread waits.
3. A thread relinquishes the lock simply by returning from the synchronized method, allowing the next
thread waiting for this lock to proceed.
4. Synchronized methods are useful in situations where methods can manipulate the state of an object in
ways that can corrupt the state if executed concurrently. This is called a race condition. It occurs when
two or more threads simultaneously update the same value, and as a consequence, leave the value in
an undefined or inconsistent state. While a thread is inside a synchronized method of an object, all
other threads that wish to execute this synchronized method or any other synchronized method of the
object will have to wait until it gets the lock. This restriction does not apply to the thread that already
has the lock and is executing a synchronized method of the object. Such a method can invoke other
synchronized methods of the object without being blocked.
5. The non-synchronized methods of the object can of course be called at any time by any thread.
6. If you declare any method as synchronized, it is known as synchronized method.
7. Synchronized method is used to lock an object for any shared resource.
8. When a thread invokes a synchronized method, it automatically acquires the lock for that object and
releases it when the thread completes its task.
9. Any method is specified with the keyword synchronized is only executed by one thread at a time. If
any thread wants to implement the synchronized method, firstly it has to obtain the objects lock. If the
lock is already held by another thread, then calling thread has to wait.
10. Synchronized methods are useful in those situations where methods are executed concurrently, so that
these can be intercommunicate control the state of an object in ways that can corrupt the state if .
11. Stack implementations usually define the two operations push and pop of elements as synchronized,
that‘s why pushing and popping are mutually exclusive process.
For Example - if several threads were sharing a stack, if one thread is popping the
element on the stack then another thread would not be able to pushing the element
on the stack.
121
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
122
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Below is an example shows how synchronized methods and object locks are used to
coordinate access to a common object by multiple threads. If the ‘synchronized’
keyword is removed, the message is displayed in random fashion.
public class SyncMethodsExample extends Thread
{
static String[] msg = { "Beginner", "java", "tutorial,", ".,", "com","is", "the", "best" };
public SyncMethodsExample(String id)
{
super(id);
}
public static void main(String[] args)
{
SyncMethodsExample thread1 = new SyncMethodsExample("thread1: ");
SyncMethodsExample thread2 = new SyncMethodsExample("thread2: ");
thread1.start();
thread2.start();
boolean t1IsAlive = true;
boolean t2IsAlive = true;
do
{
if (t1IsAlive && !thread1.isAlive())
{
t1IsAlive = false;
System.out.println("t1 is dead.");
}
if (t2IsAlive && !thread2.isAlive())
{
t2IsAlive = false;
System.out.println("t2 is dead.");
}
}
while (t1IsAlive || t2IsAlive);
}
void randomWait()
{
try
{
Thread.currentThread().sleep((long) (3000 * Math.random()));
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
}
public synchronized void run()
{
SynchronizedOutput.displayList(getName(), msg);
}}
123
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
class SynchronizedOutput
{
// if the 'synchronized' keyword is removed, the message
// is displayed in random fashion
public static synchronized void displayList(String name, String list[])
{
for (int i = 0; i < list.length; i++)
{
SyncMethodsExample t = (SyncMethodsExample) Thread.currentThread();
t.randomWait();
System.out.println(name + list[i]);
}
}
}
Output
thread1: Beginner
thread1: java
thread1: tutorial,
thread1: .,
thread1: com
thread1: is
thread1: the
thread1: best
t1 is dead.
thread2: Beginner
thread2: java
thread2: tutorial,
thread2: .,
thread2: com
thread2: is
thread2: the
thread2: best
t2 is dead.
124
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
125
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
126
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SYNCHRONIZED BLOCKS
Static methods synchronize on the class lock. Acquiring and relinquishing a class lock by a thread in
order to execute a static synchronized method, proceeds analogous to that of an object lock for a
synchronized instance method.
A thread acquires the class lock before it can proceed with the execution of any static synchronized
method in the class, blocking other threads wishing to execute any such methods in the same class.
This, of course, does not apply to static, non-synchronized methods, which can be invoked at any time.
Synchronization of static methods in a class is independent from the synchronization of instance
methods on objects of the class.
A subclass decides whether the new definition of an inherited synchronized method will remain
synchronized in the subclass.
The synchronized block allows execution of arbitrary code to be synchronized on the lock of an
arbitrary object.
The case with synchronized methods, where the execution of the method is
synchronized on the lock of the current object:
public Object method()
{
synchronized (this) // Synchronized block on current object
{
// method block
}
}
127
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
128
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
NOTE:-Inner classes can access data in their enclosing context. An inner object might need to
synchronize on its associated outer object, in order to ensure integrity of data in the latter. This is
illustrated in the following code where the synchronized block at (5) uses the special form of the this
reference to synchronize on the outer object associated with an object of the inner class. This setup
ensures that a thread executing the method setPi() in an inner object can only access the private
double field myPi at (2) in the synchronized block at (5), by first acquiring the lock on the associated
outer object. If another thread has the lock of the associated outer object, the thread in the inner
object has to wait for the lock to be relinquished before it can proceed with the execution of the
synchronized block at (5). However, synchronizing on an inner object and on its associated outer
object are independent of each other, unless enforced explicitly,
Below example shows how synchronized block and object locks are used to coordinate
access to shared objects by multiple threads.
public class SyncBlockExample extends Thread
{
static String[] msg = { "Beginner", "java", "tutorial,", ".,", "com","is", "the", "best" };
public SyncBlockExample(String id)
{
super(id);
}
public static void main(String[] args)
{
SyncBlockExample thread1 = new SyncBlockExample("thread1: ");
SyncBlockExample thread2 = new SyncBlockExample("thread2: ");
thread1.start();
thread2.start();
boolean t1IsAlive = true;
boolean t2IsAlive = true;
do
{
if (t1IsAlive && !thread1.isAlive())
{
t1IsAlive = false;
System.out.println("t1 is dead.");
}
if (t2IsAlive && !thread2.isAlive())
{
t2IsAlive = false;
System.out.println("t2 is dead.");
}
}
while (t1IsAlive || t2IsAlive);
}
129
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
void randomWait()
{
try
{
Thread.currentThread().sleep((long) (3000 * Math.random()));
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
}
public void run()
{
synchronized (System.out)
{
for (int i = 0; i < msg.length; i++)
{
randomWait();
System.out.println(getName() + msg[i]);
}
}
}
}
Output
thread1: Beginner
thread1: java
thread1: tutorial,
thread1: .,
thread1: com
thread1: is
thread1: the
thread1: best
t1 is dead.
thread2: Beginner
thread2: java
thread2: tutorial,
thread2: .,
thread2: com
thread2: is
thread2: the
thread2: best
t2 is dead.
130
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
131
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
132
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Synchronized Keyword
To synchronize above program, we must serialize access to the shared display() method, making it available to
only one thread at a time. This is done by using keyword synchronized with display() method.
Syntax:- synchronized void display (String msg)
Using Synchronised block
If you have to synchronize access to object of a class that has no synchronized methods, and you
cannot modify the code. You can use synchronized block to use it.
class First
{
public void display(String msg)
{
System.out.print ("["+msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]");
}
}
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{
fobj = fp;
msg = str;
start();
}
public void run()
{
synchronized(fobj) //Synchronized block
{ Output :
fobj.display(msg); [welcome]
} } } [new]
public class Syncro [programmer]
{
public static void main (String[] args)
{
First fnew = new First();
Second ss = new second(fnew, "welcome");
Second ss1= new second (fnew,"new");
Second ss2 = new second(fnew, "programmer");
} }
133
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Static synchronization
If you make any static method as synchronized, the lock will be on the class not on object.
134
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
135
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
SYNCHRONIZED THREADS:
In Java, the threads are executed separately to each other. These types of threads are called as asynchronous
threads. But there are two problems may be occurs with asynchronous threads.
1. Two or more threads share the similar resource (variable or method) while only one of them can
access the resource at one time.
2. If the producer and the consumer are sharing the same kind of data in a program then either
producer may make the data faster or consumer may retrieve an order of data and process it without
its existing.
3. Suppose, we have created two methods as increment( ) and decrement( ). which increases or
decreases value of the variable "count" by 1 respectively shown as:
public void increment( )
{
count++;
}
4. When the two threads are executed to access these methods (one for increment( ),another for
decrement( ) then both will distribute the variable "count". in that case, we can't be sure that what
value will be returned of variable "count".
5. To avoid this problem, Java uses monitor also known as “semaphore” to prevent data from being
corrupted by multiple threads by a keyword synchronized to coordinate them and intercommunicate
to each other. It is basically a mechanism which allows two or more threads to share all the available
resources in a sequential manner.
6. Java's synchronized is used to ensurethat only one thread is in a critical region. Critical region is a lock
area where only one thread is run (or lock) at a time. Once the thread is in its critical section, no other
thread can enter to that critical region. In that case, another thread will has to wait until the current
thread leaves its critical section.
Lock:
Lock term refers to the access approved to a particular thread that can access the shared resources. At
any given time, only one thread can hold the lock and thereby have access to the shared resource.
Every object in Java has build-in lock that only comes in action when the object has synchronized
method code. By associating a shared resource with a Java object and its lock, the object can act as a
guard, ensuring synchronized access to the resource. Only one thread at a time can access the shared
resource guarded by the object lock.
Since there is one lock per object, if one thread has acquired the lock, no other thread can acquire the
lock until the lock is not released by first thread. Acquire the lock means the thread currently in
synchronized method and released the lock means exits the synchronized method.
137
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
138
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
139
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Iterators returned by the HashMap are fail-fast in Enumeration returned by the HashTable are fail-safe
nature. in nature.
HashMap is preferred in single threaded Although HashTable is there to use in multi threaded
applications. If you want to use HashMap in multi applications, now a days it is not at all preferred.
threaded application, wrap it using Because, ConcurrentHashMap is better option than
Collections.synchronizedMap() method. HashTable.
140
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
HASHSET HASHMAP
HashSet stores the data as objects. HashMap stores the data as key-value pairs.
HashSet is slightly slower than HashMap. HashMap is slightly faster than HashSet.
141
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
CONCLUSION
HashMap and HashSet, though they spell similar, are totally two different data structures in the Java
Collection Framework. HashMap is inherited from the Map interface where as HashSet is inherited from
the Set interface. The structure in which they hold the data is also different. HashMap holds the data as key-
value pairs where as HashSet holds the data as only objects. There are also some similarities exist between
them.
142
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
143
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
144
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
145
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Q12) What happens if a start method is not invoked and the run method is directly invoked?
Ans)If a thread has been instantiated but not started its is said to be in new state. Unless until a start() method
is invoked on the instance of the thread, it will not said to be alive. If you do not call a start() method on the
newly created thread instance thread is not considered to be alive. If the start() method is not invoked and the
run() method is directly called on the Thread instance, the code inside the run() method will not run in a
separate new thread but it will start running in the existing thread.
Q13) What happens when start() is called?
Ans) A new thread of execution with a new call stack starts. The state of thread changes from new to
runnable. When the thread gets chance to execute its target run() method starts to run.
Q14) If code running is a thread creates a new thread what will be the initial priority of the
newly created thread?
Ans) When a code running in a thread creates a new thread object, the priority of the new thread is set equal
to the priority of the thread which has created it.
Q15) When jvm starts up, which thread will be started up first?
Ans) When jvm starts up the thread executing main method is started.
Q16) What are the daemon threads?
Ans) Daemon thread are service provider threads run in the background,these not used to run the application
code generally.When all user threads(non-daemon threads) complete their execution the jvm exit the
application whatever may be the state of the daemon threads. Jvm does not wait for the daemon threads to
complete their execution if all user threads have completed their execution.
To create Daemon thread set the daemon value of Thread using setDaemon(boolean value) method. By
default all the threads created by user are user thread. To check whether a thread is a Daemon thread or a
user thread use isDaemon() method.
Example of the Daemon thread is the Garbage Collector run by jvm to reclaim the unused memory by the
application. The Garbage collector code runs in a Daemon thread which terminates as all the user threads
are done with their execution.
Q18) Can the variables or classes be Synchronized?
Ans) No. Only methods and blocks can be synchronized.
Q19) How many locks does an object have?
Ans) Each object has only one lock.
Q20) Can a class have both Synchronized and non-synchronized methods?
Ans) Yes a class can have both synchronized and non-synchronized methods.
Q21) What are the two ways to create the thread?
Ans :
1.by implementing Runnable
2.by extending Thread
Q22) Explain the advantages of threading?
Ans : Advantages of multithreading over multi-tasking:
1. Reduces the computation time.
2. Improves performance of an application.
3. Threads distribute the same address space so it saves the memory.
4. Context switching between threads is usually less costly than between processes.
5. Cost of communication between threads is comparatively low.
146
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
147
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
148
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
149
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Q34)Can two threads call two different static synchronized methods of the same class?
Ans) No. The static synchronized methods of the same class always block each other as only one lock per class
exists.So no two static synchronized methods can execute at the same time.
Q35)Does a static synchronized method block a non-static synchronized method?
Ans)No, the thread executing the static synchronized method holds a lock on the class and the thread
executing the non-satic synchronized method holds the lock on the object on which the method has been
called, these two locks are different and these threads do not block each other.
Q36) Once a thread has been started can it be started again?
Ans) No. Only a thread can be started only once in its lifetime. If you try starting a thread which has been
already started once an IllegalThreadStateException is thrown, which is a runtime exception. A thread in
runnable state or a dead thread can not be restarted.
Q37) When does deadlock occur and how to avoid it?
Ans) When a locked object tries to access a locked object which is trying to access the first locked object.
When the threads are waiting for each other to release the lock on a particular object, deadlock occurs .
Q38)What is a better way of creating multithreaded application? Extending Thread class or
implementing Runnable?
Ans) If a class is made to extend the thread class to have a multithreaded application then this subclass of
Thread can not extend any other class and the required application will have to be added to this class as it can
not be inherited from any other class. If a class is made to implement Runnable interface, then the class can
extend other class or implement other interface.
Q39) Can the start() method of the Thread class be overridden? If yes should it be
overridden?
Ans) Yes the start() method can be overridden. But it should not be overridden as it’s implementation in
thread class has the code to create a new executable thread and is specialised.
Q40) What are the methods of the thread class used to schedule the threads?
Ans) The methods are as follows:
public static void sleep(long millis) throws InterruptedException
public static void yield()
public final void join() throws InterruptedException
public final void setPriority(int priority)
public final void wait() throws InterruptedException
public final void notify()
public final void notifyAll()
Q41) Which thread related methods are available in Object class?
Ans) The methods are:
public final void wait() throws Interrupted exception
public final void notify()
public final void notifyAll()
150
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
151
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
//Implementation of ThreadLocal
public class ConnectionDispenser
{
private static class ThreadLocalConnection extends ThreadLocal
{
public Object initialValue()
{
return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());
}
}
private static ThreadLocalConnection conn = new ThreadLocalConnection();
public static Connection getConnection()
{
return (Connection) conn.get();
}
}
153
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
MyClass(NonSerial nonSerial)
{
this.nonSerial = nonSerial;
}
public static void main(String [] args)
{
NonSerial nonSer = new NonSerial();
MyClass c = new MyClass(nonSer);
try
{
FileOutputStream fs = new FileOutputStream("test1.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
FileInputStream fis = new FileInputStream("test1.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (MyClass) ois.readObject();
ois.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
On execution of above code following exception will be thrown;
java.io.NotSerializableException: NonSerial
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java)
Q55) Are the static variables saved as the part of serialization?
Ans) No. The static variables belong to the class are not the part of the state of the object so they are not
saved as the part of serialized object.
Q56)What is a transient variable?
Ans) These variables are not included in the process of serialization and are not the part of the object’s
serialized state.
154
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
155
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
Q59) Does the order in which the value of the transient variables and the state of the object
using the defaultWriteObject() method are saved during serialization matter?
Ans) Yes, while restoring the object’s state the transient variables and the serializable variables that are stored
must be restored in the same order in which they were saved.
Q60) How can one customize the Serialization process? or What is the purpose of
implementing the writeObject() and readObject() method?
Ans) When you want to store the transient variables state as a part of the serialized object at the time of
serialization the class must implement the following methods –
private void wrtiteObject(ObjectOutputStream outStream)
{
//code to save the transient variables state
//as a part of serialized object
}
private void readObject(ObjectInputStream inStream)
{
//code to read the transient variables state
//and assign it to the de-serialized object
}
public class TestCustomizedSerialization implements Serializable
{
private static final long serialVersionUID =-22L;
private String noOfSerVar;
transient private int noOfTranVar;
TestCustomizedSerialization(int noOfTranVar, String noOfSerVar)
{
this.noOfTranVar = noOfTranVar;
this.noOfSerVar = noOfSerVar;
}
private void writeObject(ObjectOutputStream os)
{
try
{
os.defaultWriteObject();
os.writeInt(noOfTranVar);
} catch (Exception e)
{
e.printStackTrace();
}
}
private void readObject(ObjectInputStream is)
{
try
{
is.defaultReadObject();
int noOfTransients = (is.readInt());
}
156
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
catch (Exception e)
{
e.printStackTrace();
}
}
public int getNoOfTranVar()
{
return noOfTranVar;
}
EXPLAIN:-
The value of transient variable ‘noOfTranVar’ is saved as part of the serialized object manually by
implementing writeObject() and restored by implementing readObject().
The normal serializable variables are saved and restored by calling defaultWriteObject() and
defaultReadObject()respectively. These methods perform the normal serialization and de-sirialization
process for the object to be saved or restored respectively.
Q61) If a class is serializable but its superclass in not, what will be the state of the instance
variables inherited from super class after deserialization?
Ans) The values of the instance variables inherited from superclass will be reset to the values they were given
during the original construction of the object as the non-serializable super-class constructor will run.
E.g.
public class ChildSerializable extends ParentNonSerializable implements Serializable
{
private static final long serialVersionUID = 1L;
String color;
ChildSerializable()
{
this.noOfWheels = 8;
this.color = "blue";
}
}
public class SubSerialSuperNotSerial
{
public static void main(String [] args)
{
ChildSerializable c = new ChildSerializable();
System.out.println("Before : - " + c.noOfWheels + " "+ c.color);
try
{
FileOutputStream fs = new FileOutputStream("superNotSerail.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c);
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
157
JAVA PART=24 CHIRADIP ASU=9874488038/9903616736
try
{
FileInputStream fis = new FileInputStream("superNotSerail.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (ChildSerializable) ois.readObject();
ois.close();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("After :- " + c.noOfWheels + " "+ c.color);
}
}
Result on executing above code –
Before : - 8 blue
After :- 4 blue
158
CHIRADIP BASU:-- 9903616736 / 9874488038
159