Multi Threading
Multi Threading
Multi Threading
Software Solutions
Multithreading
Multithreading in Java:
It doesn't block the user because threads are independent and you can
perform multiple operations at the same time.
You can perform many operations together, so it saves time.
Threads are independent, so it doesn't affect other threads if an
exception occurs in a single thread.
Multithreading uses very effectively the microprocessor time by reducing
its idle time. When the processor's idle time is reduced, the output of the
programs comes earlier. Multithreading is a concept that should be
supported by the operating system. Now-a-days, all operating systems
support multithreading.
[email protected]
Ph: 9014424466 Page 1
TechVeerendra’s
Software Solutions
Multitasking:
Example:
While typing a java program in the editor we can able to listen mp3 audio
songs at the same time we can download a file from the net all these
tasks are independent of each other and executing simultaneously and
hence it is Process based multitasking.
This type of multitasking is best suitable at "os level".
[email protected]
Ph: 9014424466 Page 2
TechVeerendra’s
Software Solutions
o A process is heavyweight.
o Switching from one process to another requires some time for saving and
loading registers, memory maps, updating lists, etc.
[email protected]
Ph: 9014424466 Page 3
TechVeerendra’s
Software Solutions
Note:
Ex:
class Test
{
public static void main(String[] args)
Thread t1=Thread.currentThread();
[email protected]
Ph: 9014424466 Page 4
TechVeerendra’s
Software Solutions
As shown in the above figure, a thread is executed inside the process. There is
context-switching between the threads. There can be multiple processes inside
the OS, and one process can have multiple threads.
If only one process exists before the processor and if the process execution is
stopped for some reason, the microprocessor becomes idle without any work.
This type of programming is known as monolithic programming. In
monolithic programming, the whole process constitutes a single module. To get
a better understanding, Lord Buddha statue in Hussain Sagar lake in
Hyderabad, India is a monolithic statue (single stone carvation). The minus
[email protected]
Ph: 9014424466 Page 5
TechVeerendra’s
Software Solutions
point of single stone is if some part is to be replaced in long future, the whole
statue is to be replaced. The same is the problem with monolithic programming
also; if a part of the program is stopped, the whole program comes to standstill.
There comes to the rescue multithreading.
A Java process can be divided into a number of threads (or to say, modules)
and each thread is given the responsibility of executing a block of statements.
That is, a thread is an in charge of a few statements of a program. If one thread
stops its execution, the execution control can be shifted to another thread.
Remember, here all threads belong to the same process. This is the advantage
of threads over monolithic programming. The ultimate result is
microprocessor idle time is reduced. The end result is output of the program
comes earlier.
[email protected]
Ph: 9014424466 Page 6
TechVeerendra’s
Software Solutions
If the execution shifts between the threads of the same process, it is known
as lightweight process. If the execution shifts between the threads of different
processes, it is known as heavyweight process.
[email protected]
Ph: 9014424466 Page 7
TechVeerendra’s
Software Solutions
Runnable
interface only run() method
[email protected]
Ph: 9014424466 Page 8
TechVeerendra’s
Software Solutions
Thread class:
o Thread()
o Thread(String name)
o Thread(Runnable r)
public void start(): starts the execution of the thread.JVM calls the run()
[email protected]
Ph: 9014424466 Page 9
TechVeerendra’s
Software Solutions
milliseconds.
specified miliseconds.
executing thread.
thread(depricated).
[email protected]
Ph: 9014424466 Page 10
TechVeerendra’s
Software Solutions
thread.
interrupted.
Runnable interface:
Starting a thread:
o When the thread gets a chance to execute, its target run() method will
run.
class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
[email protected]
Ph: 9014424466 Page 11
TechVeerendra’s
Software Solutions
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
class Multi implements Runnable{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi m1=new Multi();
Thread t1 =new Thread(m1);
t1.start();
}
}
Note: If you are not extending the Thread class, your class object would not
be treated as a thread object.So you need to explicitely create Thread class
object.
We are passing the object of our class that implements Runnable so that our
class run() method may execute.
[email protected]
Ph: 9014424466 Page 12
TechVeerendra’s
Software Solutions
Example: MyThread.java
ThreadDemo.java
[email protected]
Ph: 9014424466 Page 13
TechVeerendra’s
Software Solutions
class ThreadDemo
t1.start();//starting of a Thread
for(int i=0;i<5;i++)
System.out.println("main thread");
Whenever the thread is started, the first and foremost job it does is calling
the run() method. It is a predefined thread of Thread class. This method is the
[email protected]
Ph: 9014424466 Page 14
TechVeerendra’s
Software Solutions
heart of the thread and whatever code is expected to run by the thread should
be put here. When the execution of run() method is over, the thread dies
implicitly; naturally, its job is over.
If multiple Threads are waiting to execute then which Thread will execute 1st is
decided by "Thread Scheduler" which is part of JVM.
Under preemptive scheduling, the highest priority task executes until it enters
the waiting or dead states or a higher priority task comes into existence. Under
time slicing, a task executes for a predefined slice of time and then reenters the
pool of ready tasks. The scheduler then determines which task should execute
next, based on priority and other factors.
The following are various possible outputs for the above program.
[email protected]
Ph: 9014424466 Page 15
TechVeerendra’s
Software Solutions
In the case of t.start() a new Thread will be created which is responsible for the
execution of run() method.
But in the case of t.run() no new Thread will be created and run() method will
be executed just like a normal method by the main Thread.
In the above program if we are replacing t.start() with t.run() the following is the
output.
ThreadDemo.java
class ThreadDemo
[email protected]
Ph: 9014424466 Page 16
TechVeerendra’s
Software Solutions
for(int i=0;i<5;i++)
System.out.println("main thread");
Output:
child thread
child thread
child thread
child thread
child thread
child thread
child thread
child thread
child thread
[email protected]
Ph: 9014424466 Page 17
TechVeerendra’s
Software Solutions
child thread
main thread
main thread
main thread
main thread
main thread
For every Thread the required mandatory activities like registering the Thread
with Thread Scheduler will takes care by Thread class start() method and
programmer is responsible just to define the job of the Thread inside run()
method.
Example:
start()
[email protected]
Ph: 9014424466 Page 18
TechVeerendra’s
Software Solutions
Note: We can conclude that without executing Thread class start() method
there is no chance of starting a new Thread in java. Due to this start() is
considered as heart of multithreading.
If we are not overriding run() method then Thread class run() method will be
executed which has empty implementation and hence we won't get any output.
Example:
class ThreadDemo
t.start();
We can overload run() method but Thread class start() method always invokes
no argument run() method the other overload run() methods we have to call
explicitly then only it will be executed just like normal method.
[email protected]
Ph: 9014424466 Page 19
TechVeerendra’s
Software Solutions
Example:
ThreadDemo.java
class ThreadDemo
t.start();
Output:
No arg method
[email protected]
Ph: 9014424466 Page 20
TechVeerendra’s
Software Solutions
If we override start() method then our start() method will be executed just like a
normal method call and no new Thread will be started.
Example:
System.out.println("start method");
System.out.println("run method");
class ThreadDemo
t.start();
System.out.println("main method");
Output:
start method
[email protected]
Ph: 9014424466 Page 21
TechVeerendra’s
Software Solutions
main method
Case 7:
Output:
A thread can be in one of the five states. According to sun, there is only 4
states in thread life cycle in java new, runnable, non-runnable and terminated.
There is no running state.
But for better understanding the threads, we are explaining it in the 5 states.
[email protected]
Ph: 9014424466 Page 22
TechVeerendra’s
Software Solutions
The life cycle of the thread in java is controlled by JVM. The java thread states
are as follows:
1. New/Born
2. Ready/Runnable
3. Running
4. Non-Runnable (Blocked)
5. Dead/Terminated
Diagram:
1) New/born:
The thread is in new state if you create an instance of Thread class but before
the invocation of start() method.
In born state, the thread object is created, occupies memory but is inactive. In
the above statement t1 thread is created but is not eligible for microprocessor
time as it is inactive.
2) Ready/Runnable:
The thread is in runnable state after invocation of start() method, but the
thread scheduler has not selected it to be the running thread.
[email protected]
Ph: 9014424466 Page 23
TechVeerendra’s
Software Solutions
3) Running:
The thread is in running state if the thread scheduler has selected it.
4) Non-Runnable (Blocked):
This is the state when the thread is still alive, but is currently not eligible to
run.
5) Terminated/Dead:
Concusion:
Case 9:
After starting a Thread we are not allowed to restart the same Thread once
again otherwise we will get runtime exception saying
"IllegalThreadStateException".
Example:
t.start();//valid
[email protected]
Ph: 9014424466 Page 24
TechVeerendra’s
Software Solutions
;;;;;;;;
Example:
[email protected]
Ph: 9014424466 Page 25
TechVeerendra’s
Software Solutions
class ThreadDemo
t.start();
for(int i=0;i<10;i++)
System.out.println("main thread");
Output:
[email protected]
Ph: 9014424466 Page 26
TechVeerendra’s
Software Solutions
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
child Thread
child Thread
child Thread
child Thread
child Thread
child Thread
child Thread
child Thread
child Thread
child Thread
Note: We can't expect exact output but there are several possible outputs.
[email protected]
Ph: 9014424466 Page 27
TechVeerendra’s
Software Solutions
Case study:
Case 1: t1.start():
A new Thread will be created which is responsible for the execution of Thread
class run()method.
Output:
main thread
main thread
main thread
main thread
main thread
Case 2: t1.run():
No new Thread will be created but Thread class run() method will be executed
just like a normal method call.
Output:
main thread
main thread
main thread
main thread
main thread
Case 3: t2.start():
[email protected]
Ph: 9014424466 Page 28
TechVeerendra’s
Software Solutions
Output:
main thread
main thread
main thread
main thread
main thread
child Thread
child Thread
child Thread
child Thread
child Thread
Case 4: t2.run():
No new Thread will be created and MyRunnable run() method will be executed
just like a normal method call.
Output:
child Thread
child Thread
child Thread
child Thread
child Thread
main thread
main thread
[email protected]
Ph: 9014424466 Page 29
TechVeerendra’s
Software Solutions
main thread
main thread
main thread
Case 5: r.start():
Output:
E:\SCJP>javac ThreadDemo.java
Case 6: r.run():
No new Thread will be created and MyRunnable class run() method will be
executed just like a normal method call.
Output:
child Thread
child Thread
child Thread
child Thread
child Thread
main thread
[email protected]
Ph: 9014424466 Page 30
TechVeerendra’s
Software Solutions
main thread
main thread
main thread
main thread
In which of the above cases a new Thread will be created which is responsible
for the execution of MyRunnable run() method ?
t2.start();
t1.start();
t2.start();
t2.start();
t2.run();
r.run();
[email protected]
Ph: 9014424466 Page 31
TechVeerendra’s
Software Solutions
Output:
main method
run method
[email protected]
Ph: 9014424466 Page 32
TechVeerendra’s
Software Solutions
task1();
task2();
task3();
System.out.println(“Task1 completed”);
System.out.println(“Task2 completed”);
System.out.println(“Task3 completed”);
[email protected]
Ph: 9014424466 Page 33
TechVeerendra’s
Software Solutions
class Test{
t1.run();
String atr;
MyThread(String atr){
this.str=str;
for(int i=1;i<=10;i++){
System.out.println(str”:”+i);
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
[email protected]
Ph: 9014424466 Page 34
TechVeerendra’s
Software Solutions
class Theatre{
m1.run();
m2.run();
int wanted;
Reserve(int i){
Wanted=i;
if(available>=wanted){
[email protected]
Ph: 9014424466 Page 35
TechVeerendra’s
Software Solutions
try{
Thread.sleep(2000);//time to print
}catch(InterruptedException ie){
else{
System.out.println(“sorry no berths”);
class Test{
//need 1 berth
t1.start();
t2.start();
[email protected]
Ph: 9014424466 Page 36
TechVeerendra’s
Software Solutions
Methods:
Ex:
class TestMultiNaming1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
System.out.println(Thread.currentThread().getName());//main
TestMultiNaming1 t1=new TestMultiNaming1();
TestMultiNaming1 t2=new TestMultiNaming1();
System.out.println("Name of t1:"+t1.getName()); //Thtread-0
System.out.println("Name of t2:"+t2.getName());
[email protected]
Ph: 9014424466 Page 37
TechVeerendra’s
Software Solutions
t1.start();
t2.start();
t1.setName("Veerendra");
// System.out.println("After changing name of t1:"+t1.getName());
System.out.println(Thread.currentThread().getName());
}
}
Thread.currentThread() method.
Current Thread:
public static Thread currentThread()
Example:
class TestMultiNaming2 extends Thread{
public void run(){
System.out.println(“Inside Child”+Thread.currentThread().getName());
}
public static void main(String args[]){
TestMultiNaming2 t1=new TestMultiNaming2();
TestMultiNaming2 t2=new TestMultiNaming2();
[email protected]
Ph: 9014424466 Page 38
TechVeerendra’s
Software Solutions
t1.start();
t2.start();
}
}
[email protected]
Ph: 9014424466 Page 39
TechVeerendra’s
Software Solutions
Note: The allowed values are 1 to 10 otherwise we will get runtime exception
saying "IllegalArgumentException".
Ex:
class TestMultiPriority1 extends Thread{
public void run(){
System.out.println("running thread name is:"+Thread.currentThread().get
Name());
System.out.println("running thread priority is:"+Thread.currentThread().ge
tPriority());
}
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
[email protected]
Ph: 9014424466 Page 40
TechVeerendra’s
Software Solutions
Default priority:
The default priority only for the main Thread is 5. But for all the remaining
Threads the default priority will be inheriting from parent to child. That is
whatever the priority parent has by default the same priority will be for the
child also.
Example 1:
class MyThread extends Thread
{}
class ThreadPriorityDemo
{
public static void main(String[] args)
{
System.out.println(Thread.currentThread().getPriority());//5
Thread.currentThread().setPriority(9);
MyThread t=new MyThread();
System.out.println(t.getPriority());//9
}
}
Example 2:
class MyThread extends Thread
{
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println("child thread");
}
}
[email protected]
Ph: 9014424466 Page 41
TechVeerendra’s
Software Solutions
}
class ThreadPriorityDemo
{
public static void main(String[] args)
{
MyThread t=new MyThread();
//t.setPriority(10); //----> 1
t.start();
for(int i=0;i<10;i++)
{
System.out.println("main thread");
}
}
}
If we are commenting line 1 then both main and child Threads will have
the same priority and hence we can't expect exact execution order.
If we are not commenting line 1 then child Thread has the priority 10 and
main Thread has the priority 5 hence child Thread will get chance for
execution and after completing child Thread main Thread will get the
chance in this the output is:
Output:
child thread
child thread
child thread
child thread
child thread
child thread
child thread
[email protected]
Ph: 9014424466 Page 42
TechVeerendra’s
Software Solutions
child thread
child thread
child thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
main thread
Some operating systems(like windowsXP) may not provide proper support for
Thread priorities. We have to install separate bats provided by vendor to provide
support for priorities.
yield():
1. yield() method causes "to pause current executing Thread for giving the
2. If all waiting Threads have the low priority or if there is no waiting Threads
[email protected]
Ph: 9014424466 Page 43
TechVeerendra’s
Software Solutions
3. If several waiting Threads with same priority available then we can't expect
4. The Thread which is yielded when it get chance once again for execution is
EX:
for(int i=0;i<5;i++)
Thread.yield();
System.out.println("child thread");
class ThreadYieldDemo
[email protected]
Ph: 9014424466 Page 44
TechVeerendra’s
Software Solutions
t.start();
for(int i=0;i<5;i++)
System.out.println("main thread");
Output:
main thread
main thread
main thread
main thread
main thread
child thread
child thread
child thread
child thread
child thread
[email protected]
Ph: 9014424466 Page 45
TechVeerendra’s
Software Solutions
In the above program child Thread always calling yield() method and hence
main Thread will get the chance more number of times for execution.
Note: Some operating systems may not provide proper support for yield()
method.
Join():
If a Thread wants to wait until completing some other Thread then we should
go for join() method.
[email protected]
Ph: 9014424466 Page 46
TechVeerendra’s
Software Solutions
Example:
for(int i=0;i<5;i++)
System.out.println("Sita Thread");
try
Thread.sleep(2000);
[email protected]
Ph: 9014424466 Page 47
TechVeerendra’s
Software Solutions
class ThreadJoinDemo
t.start();
//t.join(); //--->1
for(int i=0;i<5;i++)
System.out.println("Rama Thread");
for(int i=0;i<10;i++){
System.out.println(“Kajal Thread”);
[email protected]
Ph: 9014424466 Page 48
TechVeerendra’s
Software Solutions
try{
Thread.sleep(2000);
}catch(InterruptedException ie){
Class ThreadJoinDemo{
t.start();
for(int i=0;i<10;i++){
System.out.println(“Pawan Thread”);
If we are not commenting line-1 then main Thread executes join() method on
child thread object.
Hence main() thread has to wait until completing child thread object
[email protected]
Ph: 9014424466 Page 49
TechVeerendra’s
Software Solutions
Output:
Kajal thread
Kajal thread
-------(10 times)
Pawan thread
Pawan thread
-------------(10 times)
If we are commenting line-1 then we can’t expect exact execution order and
exact output.
Example:
try
mt.join();
[email protected]
Ph: 9014424466 Page 50
TechVeerendra’s
Software Solutions
for(int i=0;i<5;i++)
System.out.println("Child Thread");
class ThreadJoinDemo
MyThread mt=Thread.currentThread();
t.start();
for(int i=0;i<5;i++)
Thread.sleep(2000);
System.out.println("Main Thread");
Output:
Main Thread
Main Thread
[email protected]
Ph: 9014424466 Page 51
TechVeerendra’s
Software Solutions
Main Thread
Main Thread
Main Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Note:
If main thread calls join() on child thread object and child thread called join()
on main thread object then both threads will wait for each other forever and
the program will be hanged(like deadlock if a Thread class join() method on the
same thread itself then the program will be hanged ).
Example :
class ThreadDemo {
Thread.currentThread().join();
--------------- --------
main main
Note: If a thread calls join() method on the same thread object then the
program will be hanged like Deadlock.
Ex: Thread.currentThread.join();
[email protected]
Ph: 9014424466 Page 52
TechVeerendra’s
Software Solutions
class Test{
Thread.currentThread.join();
Ex:
class TestJoinMethod1 extends Thread{
public void run(){
for(int i=1;i<=5;i++){
try{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
TestJoinMethod1 t1=new TestJoinMethod1();
TestJoinMethod1 t2=new TestJoinMethod1();
TestJoinMethod1 t3=new TestJoinMethod1();
t1.start();
try{
t1.join();
[email protected]
Ph: 9014424466 Page 53
TechVeerendra’s
Software Solutions
}catch(Exception e){System.out.println(e);}
t2.start();
t3.start();
}
}
Output:1
[email protected]
Ph: 9014424466 Page 54
TechVeerendra’s
Software Solutions
Ex:
class TestJoinMethod2 extends Thread{
public void run(){
for(int i=1;i<=5;i++){
try{
Thread.sleep(500);
}catch(Exception e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
TestJoinMethod2 t1=new TestJoinMethod2();
TestJoinMethod2 t2=new TestJoinMethod2();
TestJoinMethod2 t3=new TestJoinMethod2();
t1.start();
try{
t1.join(1500);
}catch(Exception e){System.out.println(e);}
t2.start();
t3.start();
}
}
[email protected]
Ph: 9014424466 Page 55
TechVeerendra’s
Software Solutions
Output:1
class TestJoinMethod3 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestJoinMethod3 t1=new TestJoinMethod3();
[email protected]
Ph: 9014424466 Page 56
TechVeerendra’s
Software Solutions
TestJoinMethod3 t2=new TestJoinMethod3();
System.out.println("Name of t1:"+t1.getName());
System.out.println("Name of t2:"+t2.getName());
System.out.println("id of t1:"+t1.getId());
t1.start();
t2.start();
t1.setName("Sonoo Jaiswal");
System.out.println("After changing name of t1:"+t1.getName());
}
}
Output:Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
running...
[email protected]
Ph: 9014424466 Page 57
TechVeerendra’s
Software Solutions
Sleep() method:
If a Thread don't want to perform any operation for a particular amount of time
then we should go for sleep() method.
Example:
class ThreadSleepDemo
[email protected]
Ph: 9014424466 Page 58
TechVeerendra’s
Software Solutions
System.out.println("M");
Thread.sleep(3000);
System.out.println("E");
Thread.sleep(3000);
System.out.println("G");
Thread.sleep(3000);
System.out.println("A");
Output:
Ex-2:
class TestSleepMethod1 extends Thread{
public void run(){
for(int i=1;i<5;i++){
try{
Thread.sleep(500);
}catch(InterruptedException e){
System.out.println(e);
}
System.out.println(i);
}
[email protected]
Ph: 9014424466 Page 59
TechVeerendra’s
Software Solutions
}
public static void main(String args[]){
TestSleepMethod1 t1=new TestSleepMethod1();
TestSleepMethod1 t2=new TestSleepMethod1();
t1.start();
t2.start();
}
}
Output:
Interrupting a Thread:
How a Thread can interrupt another thread?
Example:
[email protected]
Ph: 9014424466 Page 60
TechVeerendra’s
Software Solutions
try
for(int i=0;i<5;i++)
Thread.sleep(2000);
catch (InterruptedException e)
class ThreadInterruptDemo
t.start();
//t.interrupt(); //--->1
[email protected]
Ph: 9014424466 Page 61
TechVeerendra’s
Software Solutions
If we are commenting line 1 then main Thread won't interrupt child Thread and
hence child Thread will be continued until its completion.
If we are not commenting line 1 then main Thread interrupts child Thread and
hence child Thread won't continued until its completion in this case the output
is:
I am lazy Thread: 0
I got interrupted
Note:
Whenever we are calling interrupt() method we may not see the effect
immediately, if the target Thread is in sleeping or waiting state it will be
interrupted immediately.
If the target Thread is not in sleeping or waiting state then interrupt call
will wait until target Thread will enter into sleeping or waiting state. Once
target
Thread entered into sleeping or waiting state it will effect immediately.
In its lifetime if the target Thread never entered into sleeping or waiting
state then there is no impact of interrupt call simply interrupt call will be
wasted.
Example:
[email protected]
Ph: 9014424466 Page 62
TechVeerendra’s
Software Solutions
for(int i=0;i<5;i++)
try
Thread.sleep(3000);
catch (InterruptedException e)
class ThreadInterruptDemo1
t.start();
[email protected]
Ph: 9014424466 Page 63
TechVeerendra’s
Software Solutions
In the above program interrupt() method call invoked by main Thread will wait
until child Thread entered into sleeping state.
Once child Thread entered into sleeping state then it will be interrupted
immediately.
1. It differs from sleep() in that sleep() takes a long parameter and yield()
carries no parameter.
2. yield time is not in the hands of Programmer where as sleep() time is.
[email protected]
Ph: 9014424466 Page 64
TechVeerendra’s
Software Solutions
Synchronization in Java
Java Synchronization is better option where we want to allow only one thread
to access the shared resource.
1. Synchronized is the keyword applicable for methods and blocks but not for
classes and variables.
[email protected]
Ph: 9014424466 Page 65
TechVeerendra’s
Software Solutions
7. Every object in java has a unique lock. Whenever we are using synchronized
keyword then only lock concept will come into the picture.
[email protected]
Ph: 9014424466 Page 66
TechVeerendra’s
Software Solutions
Types of Synchronization
1. Process Synchronization
2. Thread Synchronization
Thread Synchronization:
There are two types of thread synchronization mutual exclusive and inter-
thread communication.
1. Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. static synchronization.
Mutual Exclusive
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
[email protected]
Ph: 9014424466 Page 67
TechVeerendra’s
Software Solutions
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);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
[email protected]
Ph: 9014424466 Page 68
TechVeerendra’s
Software Solutions
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output: 5
100
10
200
15
[email protected]
Ph: 9014424466 Page 69
TechVeerendra’s
Software Solutions
300
20
400
25
500
Ex
class Display
for(int i=0;i<5;i++)
System.out.print("good morning:");
try
Thread.sleep(1000);
catch (InterruptedException e)
{}
System.out.println(name);
[email protected]
Ph: 9014424466 Page 70
TechVeerendra’s
Software Solutions
Display d;
String name;
this.d=d;
this.name=name;
d.wish(name);
class SynchronizedDemo
t1.start();
t2.start();
If we are not declaring wish() method as synchronized then both Threads will
beexecuted simultaneously and we will get irregular output.
[email protected]
Ph: 9014424466 Page 71
TechVeerendra’s
Software Solutions
Output:
good morning:dhoni
good morning:yuvaraj
good morning:dhoni
good morning:yuvaraj
good morning:dhoni
good morning:yuvaraj
good morning:dhoni
good morning:yuvaraj
dhoni
Output:
good morning:dhoni
good morning:dhoni
good morning:dhoni
good morning:dhoni
good morning:dhoni
good morning:yuvaraj
good morning:yuvaraj
good morning:yuvaraj
good morning:yuvaraj
[email protected]
Ph: 9014424466 Page 72
TechVeerendra’s
Software Solutions
good morning:yuvaraj
//example of java synchronized method
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
[email protected]
Ph: 9014424466 Page 73
TechVeerendra’s
Software Solutions
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
[email protected]
Ph: 9014424466 Page 74
TechVeerendra’s
Software Solutions
t2.start();
}
}
Output: 5
10
15
20
25
100
200
300
400
500
Case study:
Case 1:
t1.start();
t2.start();
[email protected]
Ph: 9014424466 Page 75
TechVeerendra’s
Software Solutions
Diagram:
1. Every class in java has a unique lock. If a Thread wants to execute a static
synchronized method then it required class level lock.
2. Once a Thread got class level lock then it is allow to execute any static
synchronized method of that class.
[email protected]
Ph: 9014424466 Page 76
TechVeerendra’s
Software Solutions
5. Class level lock and object lock both are different and there is no
relationship between these two.
Synchronized block:
1. If very few lines of the code required synchronization then it's never
recommended to declare entire method as synchronized we have to enclose
those few lines of the code with in synchronized block.
Example:
Program of synchronized block
class Table{
void printTable(int n){
synchronized(this){//synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
[email protected]
Ph: 9014424466 Page 77
TechVeerendra’s
Software Solutions
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
[email protected]
Ph: 9014424466 Page 78
TechVeerendra’s
Software Solutions
t.printTable(100);
}
}
public class TestSynchronizedBlock1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:5
10
15
20
25
100
200
300
400
500
[email protected]
Ph: 9014424466 Page 79
TechVeerendra’s
Software Solutions
If Thread got lock of current object then only it is allowed to execute this block.
Synchronized(this){
If thread got lock of 'b' object then only it is allowed to execute this block.
Synchronized(b){
Synchronized(Display.class){
If thread got class level lock of Display then only it allowed to execute this
block.
Note: As the argument to the synchronized block we can pass either object
reference or
".class file" and we can't pass primitive values as argument [because lock
concept is only for objects and classes but not for primitives].
Example:
int x=b;
[email protected]
Ph: 9014424466 Page 80
TechVeerendra’s
Software Solutions
Synchronized(x){}
Output:
Unexpected type.
Found: int
Required: reference
Static synchronization
If you make any static method as synchronized, the lock will be on the class
not on object.
[email protected]
Ph: 9014424466 Page 81
TechVeerendra’s
Software Solutions
Suppose there are two objects of a shared class(e.g. Table) named object1 and
object2.In case of synchronized method and synchronized block there cannot
be interference between t1 and t2 or t3 and t4 because t1 and t2 both refers to
a common object that have a single lock.But there can be interference between
t1 and t3 or t2 and t4 because t1 acquires another lock and t3 acquires
another lock.I want no interference between t1 and t3 or t2 and t4.Static
synchronization solves this problem.
class Table{
synchronized static void printTable(int n){
for(int i=1;i<=10;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){}
}
}
}
class MyThread1 extends Thread{
public void run(){
[email protected]
Ph: 9014424466 Page 82
TechVeerendra’s
Software Solutions
Table.printTable(1);
}
}
class MyThread2 extends Thread{
public void run(){
Table.printTable(10);
}
}
class MyThread3 extends Thread{
public void run(){
Table.printTable(100);
}
}
class MyThread4 extends Thread{
public void run(){
Table.printTable(1000);
}
}
[email protected]
Ph: 9014424466 Page 83
TechVeerendra’s
Software Solutions
public class TestSynchronization4{
public static void main(String t[]){
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
MyThread3 t3=new MyThread3();
MyThread4 t4=new MyThread4();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output: 1
10
10
20
30
[email protected]
Ph: 9014424466 Page 84
TechVeerendra’s
Software Solutions
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
[email protected]
Ph: 9014424466 Page 85
TechVeerendra’s
Software Solutions
9000
10000
[email protected]
Ph: 9014424466 Page 86
TechVeerendra’s
Software Solutions
wait(), notify() and notifyAll() methods are available in Object class but
not in Thread class because Thread can call these methods on any
common object.
To call wait(), notify() and notifyAll() methods compulsory the current
Thread should be owner of that object i.e., current Thread should has
lock of that object i.e., current Thread should be in synchronized area.
Hence we can call wait(), notify() and notifyAll() methods only from
synchronized area otherwise we willget runtime exception saying
IllegalMonitorStateException.
Once a Thread calls wait() method on the given object 1st it releases the
lock of that object immediately and entered into waiting state.
Once a Thread calls notify() (or) notifyAll() methods it releases the lock of
that object but may not immediately.
Except these (wait(),notify(),notifyAll()) methods there is no other
place(method) where the lock release will be happen.
[email protected]
Ph: 9014424466 Page 87
TechVeerendra’s
Software Solutions
Once a Thread calls wait(), notify(), notifyAll() methods on any object then it
releases the lock of that particular object but not all locks it has.
Example 1:
class ThreadA
b.start();
synchronized(b)
[email protected]
Ph: 9014424466 Page 88
TechVeerendra’s
Software Solutions
b.wait();
System.out.println(b.total);
int total=0;
synchronized(this)
for(int i=0;i<=100;i++)
total=total+i;
this.notify();
[email protected]
Ph: 9014424466 Page 89
TechVeerendra’s
Software Solutions
Output:
5050
class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
synchronized void deposit(int amount){
[email protected]
Ph: 9014424466 Page 90
TechVeerendra’s
Software Solutions
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();
}}
going to deposit...
deposit completed...
withdraw completed
[email protected]
Ph: 9014424466 Page 91
TechVeerendra’s
Software Solutions
Example 2:
After producing the items producer Thread call notify() method on the queue to
give notification so that consumer Thread will get that notification and
consume items.
Ex:
[email protected]
Ph: 9014424466 Page 92
TechVeerendra’s
Software Solutions
Notify vs notifyAll():
We can use notify() method to give notification for only one Thread. If multiple
Threads are waiting then only one Thread will get the chance and remaining
Threads has to wait for further notification. But which Thread will be
notify(inform) we can't expect exactly it depends on JVM.
We can use notifyAll() method to give the notification for all waiting Threads. All
waiting Threads will be notified and will be executed one by one, because they
are required lock
Note: On which object we are calling wait(), notify() and notifyAll() methods that
corresponding object lock we have to get but not other object locks.
[email protected]
Ph: 9014424466 Page 93
TechVeerendra’s
Software Solutions
1. Once a Thread calls wait() on any Object immediately it will entered into
waiting state without releasing the lock ?
NO
2. Once a Thread calls wait() on any Object it reduces the lock of that Object
but not immediately ?
NO
3. Once a Thread calls wait() on any Object it immediately releases all locks
whatever it has and entered into waiting state ?
NO
4. Once a Thread calls wait() on any Object it immediately releases the lock of
that Object and entered into waiting state ?
[email protected]
Ph: 9014424466 Page 94
TechVeerendra’s
Software Solutions
YES
5. Once a Thread calls notify() on any Object it immediately releases the lock of
that Object ?
NO
6. Once a Thread calls notify() on any Object it releases the lock of that Object
but may not immediately ?
YES
Dead lock:
If 2 Threads are waiting for each other forever(without end) such type of
situation(infinite waiting) is called dead lock.
There are no resolution techniques for dead lock but several
prevention(avoidance) techniques are possible.
Synchronized keyword is the cause for deadlock hence whenever we are
using synchronized keyword we have to take special care.
public class TestDeadlockExample1 {
public static void main(String[] args) {
final String resource1 = "ratan jaiswal";
final String resource2 = "vimal jaiswal";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
[email protected]
Ph: 9014424466 Page 95
TechVeerendra’s
Software Solutions
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try { Thread.sleep(100);} catch (Exception e) {}
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");
}
[email protected]
Ph: 9014424466 Page 96
TechVeerendra’s
Software Solutions
}
}
};
t1.start();
t2.start();
}
}
Example:
class A
method");
try
Thread.sleep(2000);
[email protected]
Ph: 9014424466 Page 97
TechVeerendra’s
Software Solutions
catch (InterruptedException e)
{}
b.last();
class B
try
Thread.sleep(2000);
catch (InterruptedException e)
{}
a.last();
[email protected]
Ph: 9014424466 Page 98
TechVeerendra’s
Software Solutions
A a=new A();
B b=new B();
DeadLock()
t.start();
a.foo(b);//main thread
b.bar(a);//child thread
Output:
[email protected]
Ph: 9014424466 Page 99
TechVeerendra’s
Software Solutions
Daemon Threads:
The Threads which are executing in the background are called daemon
Threads.
Example:
Garbage collector
Whenever the program runs with low memory the JVM will execute
Garbage Collector to provide free memory. So that the main Thread can
continue it's execution.
We can check whether the Thread is daemon or not by using isDaemon()
method of Thread class.
[email protected]
Ph: 9014424466 Page 100
TechVeerendra’s
Software Solutions
But we can change daemon nature before starting Thread only. That is
after starting the Thread if we are trying to change the daemon nature we
will get R.E
saying IllegalThreadStateException.
Default Nature : Main Thread is always non daemon and we can't change
its daemon nature because it's already started at the beginning only.
Main Thread is always non daemon and for the remaining Threads
daemon nature will be inheriting from parent to child that is if the parent
is daemon child is also daemon and if the parent is non daemon then
child is also non daemon.
Whenever the last non daemon Thread terminates automatically all
daemon Threads will be terminated.
Example:
class DaemonThreadDemo
System.out.println(Thread.currentThread().isDaemon());
System.out.println(t.isDaemon()); 1
[email protected]
Ph: 9014424466 Page 101
TechVeerendra’s
Software Solutions
t.start();
t.setDaemon(true);
System.out.println(t.isDaemon());
Output:
false
false
RE:IllegalThreadStateException
Example:
for(int i=0;i<10;i++)
System.out.println("lazy thread");
try
Thread.sleep(2000);
catch (InterruptedException e)
{}
[email protected]
Ph: 9014424466 Page 102
TechVeerendra’s
Software Solutions
class DaemonThreadDemo
t.setDaemon(true); //-->1
t.start();
Output:
If we comment line 1 then both main & child Threads are non-Daemon ,
and hence both threads will be executed untill there completion.
If we are not comment line 1 then main thread is non-Daemon and child
thread is Daemon. Hence when ever main Thread terminates
automatically child thread will be terminated.
Lazy thread:
[email protected]
Ph: 9014424466 Page 103
TechVeerendra’s
Software Solutions
If we are commenting line 1 then both main and child Threads are non daemon
and hence both will be executed until they completion.
If we are not commenting line 1 then main Thread is non daemon and child
Thread is daemon and hence whenever main Thread terminates automatically
child Thread will be terminated.
Deadlock vs Starvation:
A low priority Thread has to wait until completing all high priority Threads.
This long waiting of Thread which ends at certain point is called starvation.
We can call stop() method to stop a Thread in the middle then it will be entered
into dead state immediately.
stop() method has been deprecated and hence not recommended to use.
suspend and resume methods:
A Thread can suspend another Thread by using suspend() method then that
Thread will be paused temporarily.
[email protected]
Ph: 9014424466 Page 104
TechVeerendra’s
Software Solutions
RACE condition:
[email protected]
Ph: 9014424466 Page 105
TechVeerendra’s
Software Solutions
Ex:
class Reentrant {
public synchronized void m() {
n();
System.out.println("this is m() method");
}
public synchronized void n() {
System.out.println("this is n() method");
}
}
In this class, m and n are the synchronized methods. The m() method
internally calls the n() method.
Now let's call the m() method on a thread. In the class given below, we are
creating thread using annonymous class.
public class ReentrantExample{
public static void main(String args[]){
final ReentrantExample re=new ReentrantExample();
[email protected]
Ph: 9014424466 Page 106
TechVeerendra’s
Software Solutions
Thread t1=new Thread(){
public void run(){
re.m();//calling method of Reentrant class
}
};
t1.start();
}}
[email protected]
Ph: 9014424466 Page 107
TechVeerendra’s
Software Solutions
Constructors:
[email protected]
Ph: 9014424466 Page 108
TechVeerendra’s
Software Solutions
Note:
[email protected]
Ph: 9014424466 Page 109
TechVeerendra’s
Software Solutions
3) void setMaxPriority();
[email protected]
Ph: 9014424466 Page 110
TechVeerendra’s
Software Solutions
8) int enumerate(Thread[] t): To Copy All Active Threads of this Group into
provided Thread Array. In this Case SubThreadGroup Threads also will be
Considered.
[email protected]
Ph: 9014424466 Page 111
TechVeerendra’s
Software Solutions
ThreadGroupArray
10) booleanisDaemon():
Ex:
super(g, name);
System.out.println("Child Thread");
try {
Thread.sleep(2000);
catch (InterruptedException e) {}
classThreadGroupDemo {
[email protected]
Ph: 9014424466 Page 112
TechVeerendra’s
Software Solutions
t1.start();
t2.start();
System.out.println(pg.activeCount());
System.out.println(pg.activeGroupCount());
pg.list();
Thread.sleep(5000);
System.out.println(pg.activeCount());
pg.list();
Output:
java.lang.ThreadGroup[name=Parent Group,maxpri=10]
java.lang.ThreadGroup[name=Child Group,maxpri=10]
Child Thread
Child Thread
java.lang.ThreadGroup[name=Parent Group,maxpri=10]
java.lang.ThreadGroup[name=Child Group,maxpri=10]
[email protected]
Ph: 9014424466 Page 113
TechVeerendra’s
Software Solutions
ThreadLocal:
Thread can Access its Local Value, can Manipulates its Value and Even can
Remove its Value.
In Every Part of the Code which is executed by the Thread we can Access its
Local Variables.
Eg:
[email protected]
Ph: 9014424466 Page 114
TechVeerendra’s
Software Solutions
Note:
☀ All the Code which is executed by the Thread has Access to Corresponding
ThreadLocal Variables.
☀ A Thread can Access its Own Local Variables and can’t Access Other
ThreadsLocal Variables.
☀ Once Thread Entered into Dead State All Local Variables are by Default
Eligible for Garbage Collection.
Methods:
2) Object initialValue();
4) void remove();
[email protected]
Ph: 9014424466 Page 115
TechVeerendra’s
Software Solutions
Ex:
[email protected]
Ph: 9014424466 Page 116
TechVeerendra’s
Software Solutions
ThreadLocalVs Inheritance:
Ex:
return "cc";
};
itl.set("pp");
[email protected]
Ph: 9014424466 Page 117
TechVeerendra’s
Software Solutions
ct.start();
classThreadLocalDemo {
pt.start();
Java.util.concurrent.locks package:
If a Thread Releases the Lock then which waiting Thread will get that Lock we
are Not having any Control on this.
We can’t Specify Maximum waiting Time for a Thread to get Lock so that it will
Wait until getting Lock, which May Effect Performance of the System and
Causes Dead Lock.
We are Not having any Flexibility to Try for Lock without waiting.
[email protected]
Ph: 9014424466 Page 118
TechVeerendra’s
Software Solutions
Lock(I):
1) void lock();
2) booleantryLock();
[email protected]
Ph: 9014424466 Page 119
TechVeerendra’s
Software Solutions
If the Lock is Unavailable then Thread can Wait until specified Amount of Time.
Still if the Lock is Unavailable then Thread can Continue its Execution.
4) void lockInterruptedly();
Acquired the Lock Unless the Current Thread is Interrupted. Acquires the Lock
if it is Available and Returns Immediately.
[email protected]
Ph: 9014424466 Page 120
TechVeerendra’s
Software Solutions
ReentrantLock
Reentrant Means a Thread can acquires Same Lock Multiple Times without any
Issue.
Constructors:
If Fairness is true then Longest Waiting Thread can acquired Lock Once it is
Avaiable i.e. if follows First - In First – Out.
If Fairness is false then we can’t give any Guarantee which Thread will get the
Lock Once it is Available.
Note: If we are Not specifying any Fairness Property then by Default it is Not
Fair.
[email protected]
Ph: 9014424466 Page 121
TechVeerendra’s
Software Solutions
1) void lock();
2) booleantryLock();
4) void lockInterruptedly();
5) void unlock();
If the Current Thread is Not Owner of the Lock then we will get Runtime
Exception Saying IllegalMonitorStateException.
[email protected]
Ph: 9014424466 Page 122
TechVeerendra’s
Software Solutions
Ex:
importjava.util.concurrent.locks.ReentrantLock;
class Test {
l.lock();
l.lock();
System.out.println(l.isLocked()); //true
System.out.println(l.isHeldByCurrentThread()); //true
System.out.println(l.getQueueLength()); //0
l.unlock();
System.out.println(l.getHoldCount()); //1
System.out.println(l.isLocked()); //true
l.unlock();
System.out.println(l.isLocked()); //false
System.out.println(l.isFair()); //false
[email protected]
Ph: 9014424466 Page 123
TechVeerendra’s
Software Solutions
Ex:
importjava.util.concurrent.locks.ReentrantLock;
class Display {
l.lock(); 1
System.out.println("Good Morning");
try {
Thread.sleep(2000);
catch(InterruptedException e) {}
System.out.println(name);
l.unlock(); 2
Display d;
String name;
this.d = d;
this.name = name;
[email protected]
Ph: 9014424466 Page 124
TechVeerendra’s
Software Solutions
d.wish(name);
classReentrantLockDemo {
t1.start();
t2.start();
t3.start();
Output:
Good Morning
Dhoni
Good Morning
Dhoni
Good Morning
Dhoni
[email protected]
Ph: 9014424466 Page 125
TechVeerendra’s
Software Solutions
Good Morning
Dhoni
Good Morning
Dhoni
Good Morning
Yuva Raj
Good Morning
Yuva Raj
Good Morning
Yuva Raj
Good Morning
Yuva Raj
Good Morning
Yuva Raj
Good Morning
ViratKohli
Good Morning
ViratKohli
Good Morning
ViratKohli
Good Morning
ViratKohli
Good Morning
[email protected]
Ph: 9014424466 Page 126
TechVeerendra’s
Software Solutions
ViratKohli
If we are Not Commenting then the Threads will be executed One by One and
Hence we will get Regular Output
importjava.util.concurrent.locks.ReentrantLock;
MyThread(String name) {
super(name);
if(l.tryLock()) {
try {
Thread.sleep(2000);
catch(InterruptedException e) {}
l.unlock();
else {
[email protected]
Ph: 9014424466 Page 127
TechVeerendra’s
Software Solutions
classReentrantLockDemo {
t1.start();
t2.start();
Output:
Ex:
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.locks.ReentrantLock;
MyThread(String name) {
super(name);
}
[email protected]
Ph: 9014424466 Page 128
TechVeerendra’s
Software Solutions
do {
try {
if(l.tryLock(1000, TimeUnit.MILLISECONDS)) {
Thread.sleep(5000);
l.unlock();
break;
else {
catch(InterruptedException e) {}
while(true);
classReentrantLockDemo {
t1.start();
t2.start();
[email protected]
Ph: 9014424466 Page 129
TechVeerendra’s
Software Solutions
Output:
Thread Pools:
Creating a New Thread for Every Job May Create Performance and Memory
Problems.
service.submit(job);
[email protected]
Ph: 9014424466 Page 130
TechVeerendra’s
Software Solutions
service.shutdown();
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
String name;
PrintJob(String name) {
this.name = name;
try {
Thread.sleep(10000);
catch (InterruptedException e) {}
class ExecutorDemo {
PrintJob[] jobs = {
newPrintJob("Durga"),
[email protected]
Ph: 9014424466 Page 131
TechVeerendra’s
Software Solutions
newPrintJob("Ravi"),
newPrintJob("Nagendra"),
newPrintJob("Pavan"),
newPrintJob("Bhaskar"),
newPrintJob("Varma")
};
service.submit(job);
service.shutdown();
Output:
[email protected]
Ph: 9014424466 Page 132
TechVeerendra’s
Software Solutions
[email protected]
Ph: 9014424466 Page 133