Unit-2 PPT-2
Unit-2 PPT-2
Multithreading
• Java provides built-in support for multithreaded programming. A multithreaded
program contains two or more parts that can run concurrently. Each part of such a
program is called a thread, and each thread defines a separate path of execution.
Thus, multithreading is a specialized form of multitasking.
• Multithreading in Java is a process of executing multiple threads
simultaneously.
• A thread is a lightweight sub-process, the smallest unit of processing.
Multiprocessing and multithreading, both are used to achieve multitasking.
• However, we use multithreading than multiprocessing because threads use a
shared memory area. They don't allocate separate memory area so saves memory,
and context-switching between the threads takes less time than process.
• Java Multithreading is mostly used in games, animation, etc.
Advantages of Java Multithreading
1) It doesn't block the user because threads are independent and you
can perform multiple operations at the same time.
2) You can perform many operations together, so it saves time.
3) Threads are independent, so it doesn't affect other threads if an
exception occurs in a single thread.
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use
multitasking to utilize the CPU. Multitasking can be achieved in two ways:
Process-based Multitasking (Multiprocessing)
Thread-based Multitasking (Multithreading)
1) Process-based Multitasking (Multiprocessing)
Each process has an address in memory. In other words, each process
allocates a separate memory area.
A process is heavyweight.
Cost of communication between the process is high.
Switching from one process to another requires some time for saving and
loading registers, memory maps, updating lists, etc.
2) Thread-based Multitasking (Multithreading)
Threads share the same address space.
A thread is lightweight.
Cost of communication between the thread is low.
What is Thread in java
A thread is a lightweight subprocess, the smallest unit of processing. It
is a separate path of execution.
Threads are independent. If there occurs exception in one thread, it
doesn't affect other threads. It uses a shared memory area.
Difference between Multithreading and multitasking
The Java Thread Model
• The Java run-time system depends on threads for many things, and all the class
libraries are designed with multithreading in mind. In fact, Java uses threads to enable
the entire environment to be asynchronous. This helps reduce inefficiency by
preventing the waste of CPU cycles.
• Single-threaded systems use an approach called an event loop with polling. In this
model, a single thread of control runs in an infinite loop, polling a single event queue
to decide what to do next. Once this polling mechanism returns with, say, a signal that
a network file is ready to be read, then the event loop dispatches control to the
appropriate event handler. Until this event handler returns, nothing else can happen in
the program.
• This wastes CPU time. It can also result in one part of a program dominating the
system and preventing any other events from being processed. In general, in a single-
threaded environment, when a thread blocks (that is, suspends execution) because it is
waiting for some resource, the entire program stops running.
• The benefit of Java’s multithreading is that the main loop/polling
mechanism is eliminated.
• One thread can pause without stopping other parts of your program.
• most readers know, over the past few years, multi-core systems have
become commonplace. Of course, single-core systems are still in
widespread use. It is important to understand that Java’s multithreading
features work in both types of systems. In a single core system,
concurrently executing threads share the CPU, with each thread
receiving a slice of CPU time.
• Therefore, in a single-core system, two or more threads do not actually
run at the same time, but idle CPU time is utilized. However, in multi-
core systems, it is possible for two or more threads to actually execute
simultaneously. In many cases, this can further improve program
efficiency and increase the speed of certain operations.
Thread Life Cycle
• Thread is a program which has separate path of execution. A program
would contain many threads. Multi-threading ensures that the CPU time is
not wasted.
• The JVM will create main thread and this main thread is the one which is
going to run main method. Any thread that is created by the user is called
has child thread.
• For each thread there will be the priority, we can set it using setPriority(int
i) method, where i is the value from 1-10, 1 means low priority and 10 is
the maximum priority. The main thread priority is 5.
• We can get the priority of the thread by calling getPriority( ) method. If we
don’t set any priority the default priority will be 5.
States of thread
• Threads exist in several states. Here is a general description. A thread
can be running.
• It can be ready to run as soon as it gets CPU time. A running thread
can be suspended, which temporarily halts its activity.
• A suspended thread can then be resumed, allowing it to pick up where
it left off.
• A thread can be blocked when waiting for a resource. At any time, a
thread can be terminated, which halts its execution immediately. Once
terminated, a thread cannot be resumed.
Thread States in Java
• In the most general sense, you create a thread by instantiating an object of type
Thread.
• You can implement the Runnable interface.
• You can extend the Thread class, itself.
Implementing Runnable
• The easiest way to create a thread is to create a class that implements the Runnable
interface.
• Runnable abstracts a unit of executable code. You can construct a thread on any
object that implements Runnable.
• To implement Runnable, a class need only implement a single method called run( ),
which is declared like this:
public void run( )
• Inside run( ), you will define the code that constitutes the new thread. It is important
to understand that run( ) can call other methods, use other classes, and declare
variables, just like the main thread can.
• The only difference is that run( ) establishes the entry point for another, concurrent
thread of execution within your program. This thread will end when run( ) returns.
• After you create a class that implements Runnable, you will instantiate an object of
type Thread from within that class. Thread defines several constructors. The one
that we will use is shown here:
Thread(Runnable threadOb, String threadName)
• In this constructor, threadOb is an instance of a class that implements the Runnable
interface. This defines where execution of the thread will begin. The name of the new
thread is specified by threadName.
• After the new thread is created, it will not start running until you call its start( )
method, which is declared within Thread.
• In essence, start( ) executes a call to run( ). The start( ) method is shown here:
void start( )
Here is an example that creates a new thread and starts it running:
// Create a second thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread // This is the entry point for the second thread.
} public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
Output:
Continued……. Child thread: Thread[Demo Thread,5,main]
class ThreadDemo { Main Thread: 5
Child Thread: 5
public static void main(String args[ ] ) {
Child Thread: 4
new NewThread(); // create a new thread Main Thread: 4
try { Child Thread: 3
Child Thread: 2
for(int i = 5; i > 0; i--) {
Main Thread: 3
System.out.println("Main Thread: " + i); Child Thread: 1
Thread.sleep(1000); Exiting child thread.
Main Thread: 2
} Main Thread: 1
} catch (InterruptedException e) { Main thread exiting.
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Extending Thread
• The second way to create a thread is to create a new class that extends
Thread, and then to create an instance of that class. The extending
class must override the run( ) method, which is the entry point for the
new thread. It must also call start( ) to begin execution of the new
thread.
// Create a second thread by extending Thread class ExtendThread {
class NewThread extends Thread { public static void main(String args[]) {
NewThread() {
new NewThread(); // create a new thread
try {
// Create a new, second thread for(int i = 5; i > 0; i--) {
super("Demo Thread"); System.out.println("Main Thread: " + i);
System.out.println("Child thread: " + this); Thread.sleep(1000);
}
start(); // Start the thread
} catch (InterruptedException e) {
} System.out.println("Main thread interrupted.");
// This is the entry point for the second thread. }
System.out.println("Main thread exiting.");
public void run() {
}
try { }
for(int i = 5; i > 0; i--) { Output:
System.out.println("Child Thread: " + i); Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Thread.sleep(500); Child Thread: 5
Child Thread: 4
} Main Thread: 4 Notice the call to super( ) inside NewThread. This
Child Thread: 3 invokes the following form of the
} catch (InterruptedException e) { Child Thread: 2 Thread constructor:
System.out.println("Child interrupted."); Main Thread: 3 public Thread(String threadName)
Child Thread: 1 Here, threadName specifies the name of the thread.
} Exiting child thread.
Main Thread: 2
System.out.println("Exiting child thread."); Main Thread: 1
Main thread exiting.
}
Creating Multiple Threads
• So far, you have been using only two threads: the main // This is the entry point for thread.
thread and one child thread. public void run() {
• However, your program can spawn as many threads as it try {
needs. For example, the following program creates three for(int i = 5; i > 0; i--) {
child threads: System.out.println(name + ": " + i);
// Create multiple threads. Thread.sleep(1000);
}
class NewThread implements Runnable { } catch (InterruptedException e) {
String name; // name of thread System.out.println(name + "Interrupted");
Thread t; }
System.out.println(name + " exiting.");
NewThread(String threadname) { }
name = threadname; }
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
Continued… New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
class MultiThreadDemo { New thread: Thread[Three,5,main]
One: 5
public static void main(String args[]) {
Two: 5
new NewThread("One"); // start threads Three: 5
new NewThread("Two"); One: 4
new NewThread("Three"); Two: 4
try { Three: 4
// wait for other threads to end One: 3
Three: 3
Thread.sleep(10000);
Two: 3
} catch (InterruptedException e) { One: 2
System.out.println("Main thread Interrupted"); Three: 2
} Two: 2
System.out.println("Main thread exiting."); One: 1
} Three: 1
Two: 1
}
One exiting.
Two exiting.
Three exiting.
Main thread exiting.
Using isAlive( ) and join( )
• As mentioned, often you will want the main thread to finish last. In the preceding
examples, this is accomplished by calling sleep( ) within main( ), with a long enough
delay to ensure that all child threads terminate prior to the main thread
• How can one thread know when another thread has ended? Fortunately, Thread
provides a means by which you can answer this question.
• Two ways exist to determine whether a thread has finished. First, you can call
isAlive( ) on the thread.
• This method is defined by Thread, and its general form is shown here:
• The isAlive( ) method returns true if the thread upon which it is called is still
running. It returns false otherwise.
• While isAlive( ) is occasionally useful, the method that you will more commonly
use to wait for a thread to finish is called join( ), shown here:
final void join( ) throws InterruptedException
• This method waits until the thread on which it is called terminates. Its name
comes from the concept of the calling thread waiting until the specified thread
joins it.
• Additional forms of join( ) allow you to specify a maximum amount of time that
you want to wait for the specified thread to terminate.
preceding example that uses join( ) to ensure that the main thread is the last to stop. It also demonstrates
the isAlive( ) method.
// Using join() to wait for threads to finish. // This is the entry point for thread.
class NewThread implements Runnable { public void run() {
try {
String name; // name of thread for(int i = 5; i > 0; i--) {
Thread t; System.out.println(name + ": " + i);
NewThread(String threadname) { Thread.sleep(1000);
}
name = threadname; } catch (InterruptedException e) {
t = new Thread(this, name); System.out.println(name + " interrupted.");
}
System.out.println("New thread: " + t);
System.out.println(name + " exiting.");
t.start(); // Start the thread }
} }
class DemoJoin {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
NewThread ob3 = new NewThread("Three");
System.out.println("Thread One is alive: " + ob1.t.isAlive());
System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
Continued……..
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Thread One is alive: "+ ob1.t.isAlive());
System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
System.out.println("Main thread exiting.");
}
}
• New thread: Thread[One,5,main] One: 2
• New thread: Thread[Two,5,main] Two: 2
Three: 2
• New thread: Thread[Three,5,main]
One: 1
• Thread One is alive: true Two: 1
• Thread Two is alive: true Three: 1
Two exiting.
• Thread Three is alive: true Three exiting.
• Waiting for threads to finish. One exiting.
• One: 5 Thread One is alive: false
Thread Two is alive: false
• Two: 5 Thread Three is alive: false
• Three: 5 Main thread exiting.
As you can see, after the calls to join( ) return, the threads have
• One: 4
stopped executing
• Two: 4
• Three: 4
• One: 3
• Two: 3
• Three: 3
• Sometimes, suspending execution of a thread is useful. For example, a separate
thread can be used to display the time of day. If the user doesn’t want a clock, then
its thread can be suspended. Whatever the case, suspending a thread is a simple
matter. Once suspended, restarting the thread is also a simple matter.
• The suspend( ) method of the Thread class was deprecated by Java 2 several
years ago. This was done because suspend( ) can sometimes cause serious system
failures.
• The resume( ) method is also deprecated. It does not cause problems, but cannot
be used without the suspend( ) method as its counterpart.
• The stop( ) method of the Thread class, too, was deprecated by Java 2. This was
done because this method can sometimes cause serious system failures.
• Assume that a thread is writing to a critically important data structure and has
completed only part of its changes. If that thread is stopped at that point, that data
structure might be left in a corrupted state. The trouble is that stop( ) causes any
lock the calling thread holds to be released. Thus, the corrupted data might be used
by another thread that is waiting on the same lock.
• thread must be designed so that the run( ) method periodically checks to determine
whether that thread should suspend, resume, or stop its own execution. Typically,
this is accomplished by establishing a flag variable that indicates the execution state
of the thread. As long as this flag is set to “running,” the run( ) method must
continue to let the thread execute. If this variable is set to “suspend,” the thread must
pause. If it is set to “stop,” the thread must terminate. Of course, a variety of ways
exist in which to write such code, but the central theme will be the same for all
programs.
// Suspending and resuming a thread the modern way. // This is the entry point for thread.
class NewThread implements Runnable { public void run() {
try {
String name; // name of thread for(int i = 15; i > 0; i--) {
Thread t; System.out.println(name + ": " + i);
boolean suspendFlag; Thread.sleep(200);
synchronized(this) {
NewThread(String threadname) { while(suspendFlag) {
name = threadname; wait();
t = new Thread(this, name); }}}}
catch (InterruptedException e) {
System.out.println("New thread: " + t); System.out.println(name + " interrupted.");
suspendFlag = false; }
System.out.println(name + " exiting.");
t.start(); // Start the thread
}
} synchronized void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
} catch (InterruptedException e) {
class SuspendResume { System.out.println("Main thread Interrupted");
public static void main(String args[]) { }
// wait for threads to finish
NewThread ob1 = new NewThread("One"); try {
NewThread ob2 = new NewThread("Two"); System.out.println("Waiting for threads to finish.");
ob1.t.join();
try {
ob2.t.join();
Thread.sleep(1000); } catch (InterruptedException e) {
ob1.mysuspend(); System.out.println("Main thread Interrupted");
}
System.out.println("Suspending thread One"); System.out.println("Main thread exiting.");
Thread.sleep(1000); }
}
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
Obtaining A Thread’s State
• a thread can exist in a number of different states. You can obtain the current state
of a thread by calling the getState( ) method defined by Thread. It is shown here:
Thread.State getState( )
• It returns a value of type Thread.State that indicates the state of the thread at the
time at which the call was made. State is an enumeration defined by Thread.
• An enumeration is a list of named constants.
Thread.State ts = thrd.getState();
if(ts == Thread.State.RUNNABLE) // ...
• It is important to understand that a thread’s state may change after the call to getState( ). Thus, depending on
the circumstances, the state obtained by calling getState( ) may not reflect the actual state of the thread only a
moment later.