0% found this document useful (0 votes)
44 views33 pages

Multi Threading

The document discusses multithreading in Java. It describes thread states like new, runnable, waiting, etc. It covers creating threads using Runnable interface and extending Thread class. It also discusses thread synchronization, inter-thread communication using wait(), notify(), notifyAll() and the producer-consumer problem.

Uploaded by

Ina Shivdasani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views33 pages

Multi Threading

The document discusses multithreading in Java. It describes thread states like new, runnable, waiting, etc. It covers creating threads using Runnable interface and extending Thread class. It also discusses thread synchronization, inter-thread communication using wait(), notify(), notifyAll() and the producer-consumer problem.

Uploaded by

Ina Shivdasani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 33

Multithreading

Introduction
 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.
 Java allows a program to have multiple threads running
concurrently.
 Multithreading enables you to write very efficient
programs that make maximum use of the CPU, because
idle time can be kept to a minimum.
Thread LifeCycle
States of Thread Life Cycle
 New: A new thread begins its life cycle in the new state. It remains in this
state until the program starts the thread. It is also referred to as a born thread.
 Runnable: After a newly born thread is started, the thread becomes runnable.
A thread in this state is considered to be executing its task.
 Waiting: Sometimes a thread transitions to the waiting state while the thread
waits for another thread to perform a task. A thread transitions back to the
runnable state only when another thread signals the waiting thread to continue
executing.
 Timed waiting: A runnable thread can enter the timed waiting state for a
specified interval of time. A thread in this state transitions back to the
runnable state when that time interval expires or when the event it is waiting
for occurs.
 Terminated: A runnable thread enters the terminated state when it completes
its task or otherwise terminates.
Thread Priorities
 Every Java thread has a priority that helps the
operating system determine the order in which
threads are scheduled.
 Java 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).
Creating Thread
 Java defines two ways in which a thread can be
created:
 By implementing the Runnable interface.
 By extending the Thread class, itself.
Runnable Interface
 To implement Runnable, a class need only implement a single
method called run( ), which is declared like this:
public void run( );
 You will define the code that constitutes the new thread inside
run() method. It is important to understand that run() can call
other methods, use other classes, and declare variables, just like
the main thread can.
 After you create a class that implements Runnable, you will
instantiate an object of type Thread from within that class.
Thread defines several constructors.
Example
class NewThread implements Runnable{
Thread t;
NewThread(){
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the 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.");
}}
class ThreadDemo
{
public static void main(String args[])
{
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--){
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e){
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Output
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Child Thread: 3
Main Thread: 4
Child Thread: 2
Child Thread: 1
Main Thread: 3
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Thread Class
 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.
Example
class NewThread extends Thread {
NewThread() {
super("Demo Thread");
System.out.println("Child thread: " + this);
start(); // Start the 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.");
}}
class ExtendThread {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
Output
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Thread Methods
1. public void start()
Starts the thread in a separate path of execution, then invokes the
run() method on this Thread object.
2. public void run()
If this Thread object was instantiated using a separate Runnable
target, the run() method is invoked on that Runnable object.
3. public final void setName(String name)
Changes the name of the Thread object. There is also a
getName() method for retrieving the name.
4. public final void setPriority(int priority)
Sets the priority of this Thread object. The possible values are
between 1 and 10.
5. public final void setDaemon(boolean on)
A parameter of true denotes this Thread as a daemon thread.
6. 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.
7. public void interrupt()
Interrupts this thread, causing it to continue execution if it was
blocked for any reason.
8. public final 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.
Synchronization
 When two or more threads need access to a shared
resource, they need some way to ensure that the
resource will be used by only one thread at a time.
 The process by which this synchronization is achieved
is called thread synchronization.
 The synchronized keyword in Java creates a block of
code referred to as a critical section. Every Java object
with a critical section of code gets a lock associated
with the object. To enter a critical section, a thread
needs to obtain the corresponding object's lock.
 This is the general form of the synchronized statement:
synchronized(object)
{ // statements to be synchronized }
 Here, object is a reference to the object being
synchronized. A synchronized block ensures that a call
to a method that is a member of object occurs only after
the current thread has successfully entered object's
monitor
Example
class Callme
{
void call(String msg)
{
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted"); }
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ; msg = s;
t = new Thread(this);
t.start(); }
public void run() {
synchronized(target)
{ target.call(msg); }
} }
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
try {
ob1.t.join(); ob2.t.join(); ob3.t.join(); }
catch(InterruptedException e)
{
System.out.println("Interrupted"); }
} }
Output
[Hello]
[World]
[Synchronized]
InterThread Communication
 Consider the classic queuing problem, where one thread
is producing some data and another is consuming it.
Suppose that the producer has to wait until the
consumer is finished before it generates more data.
 In a polling system, the consumer would waste many
CPU cycles while it waited for the producer to produce.
Once the producer was finished, it would start polling,
wasting more CPU cycles waiting for the consumer to
finish, and so on. Clearly, this situation is undesirable.
To avoid polling, Java includes an elegant interprocess
communication mechanism via the following methods:
 wait( ): This method tells the calling thread to give up the
monitor and go to sleep until some other thread enters the same
monitor and calls notify( ).
 notify( ): This method wakes up the first thread that called
wait() on the same object.
 notifyAll( ): This method wakes up all the threads that called
wait( ) on the same object.c The highest priority thread will run
first.
 These methods are implemented as final methods in Object,
so all classes have them. All three methods can be called only
from within a synchronized context.
Producer Consumer Problem
 The following sample program consists of four classes:
Q, the queue that you're trying to synchronize;
Producer, the threaded object that is producing queue
entries; Consumer, the threaded object that is
consuming queue entries; and PC, the tiny class that
creates the single Q, Producer, and Consumer.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try { wait(); }
catch(InterruptedException e)
{ System.out.println("InterruptedException caught"); }
System.out.println("Got: " + n);
valueSet = false; notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try { wait(); }
catch(InterruptedException e)
{ System.out.println("InterruptedException caught"); }
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify(); }
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start(); }
public void run() {
int i = 0;
while(true) {
q.put(i++); }
} }
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get(); }
} }
class PCFixed
{
public static void main(String args[])
{
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Output
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
Description
 Inside get( ), wait( ) is called. This causes its execution to
suspend until the Producer notifies you that some data is
ready.
 When this happens, execution inside get( ) resumes. After
the data has been obtained, get( ) calls notify( ). This tells
Producer that it is okay to put more data in the queue.
 Inside put( ), wait( ) suspends execution until the
Consumer has removed the item from the queue. When
execution resumes, the next item of data is put in the
queue, and notify( ) is called. This tells the Consumer
that it should now remove it.
Thank You……..

You might also like