0% found this document useful (0 votes)
4 views

Module-4-Multithreading in Java (1)

The document provides an overview of multithreaded programming in Java, detailing methods for creating threads through implementing the Runnable interface or extending the Thread class. It discusses thread management techniques such as isAlive(), join(), and inter-thread communication using wait(), notify(), and notifyAll() methods. Additionally, it covers synchronization, deadlock scenarios, and methods for suspending and resuming threads.

Uploaded by

Aman Shetty
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Module-4-Multithreading in Java (1)

The document provides an overview of multithreaded programming in Java, detailing methods for creating threads through implementing the Runnable interface or extending the Thread class. It discusses thread management techniques such as isAlive(), join(), and inter-thread communication using wait(), notify(), and notifyAll() methods. Additionally, it covers synchronization, deadlock scenarios, and methods for suspending and resuming threads.

Uploaded by

Aman Shetty
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

Multithreaded Programming

Prepared by: Prof. Masooda


Dept. of ISE, SCEM
Creating a Thread
In the most general sense, creating a thread is by instantiating an
object of type Thread.
Java defines two ways in which this can be accomplished:

1. implement the Runnable interface.

2. extend the Thread class

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 2


1) 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.
• 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( )

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 3


• Inside run( ), 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

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 4


public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 5


Output

This code is running in a thread


This code is outside of the thread

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 6


• We can use sleep() method to see the thread running clearly
• Consider the code below

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 7


package pack;
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
try {
for(int i=5;i>0;i--)
System.out.println("This code is outside of the thread");
Thread.sleep(5000);
}
catch(InterruptedException e)
{
System.out.println("intrupted");
}
}//close main() function

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 8


public void run() {
try {
for(int i=5;i>0;i--) {
System.out.println("This code is running in a thread");
Thread.sleep(5000);
}
}
catch(InterruptedException e)
{
System.out.println("intrupted");
}
}//close run()
}//close class()
12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 9
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.
• Here is the preceding program rewritten to extend Thread:

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 10


public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();

thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 11


Output:
This code is running in a thread
This code is outside of the thread

This code is outside of the thread This code is running in a thread

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 12


Using isAlive( ) and join( )
• In java, isAlive() and join() are two different methods that are used to
check whether a thread has finished its execution or not.
• The isAlive( ) method returns true if the thread upon which it is called
is still running.
• Returns false otherwise
• But, join() method is used more commonly than isAlive().
• isAlive( ) is occasionally useful

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 13


• General form of isAlive( ) :

final boolean isAlive( )

True False

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 14


join()

• 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 to wait for the specified thread to terminate.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 15


package pack;
public class isAliveExample extends Thread {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("Interrupted exception");
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 16


public static void main(String[] args) {
isAliveExample thread = new isAliveExample();
System.out.println("Thread status before starting: " +thread.isAlive());
thread.start();
System.out.println("Thread status after starting: " + thread.isAlive());
try {
// Waiting for the thread to complete
thread.join();
}
catch (InterruptedException e) {
System.out.println("Interrupted exception");
}
System.out.println("Thread status after completion: " + thread.isAlive());
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 17


Thread status before starting: false
Thread status after starting: true
Thread status after completion: false

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 18


Interthread Communication
• Java includes an elegant interprocess communication mechanism via
the wait( ), notify( ), and notifyAll( ) methods. These methods are
implemented as final methods in Object, so all classes have them. All
three methods can be called only from within a synchronized context.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 19


• 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( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same
object. One of the threads will be granted access.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 20


These methods are declared within Object, as shown here:
• final void wait( ) throws InterruptedException
• final void notify( )
• final void notifyAll( )

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 21


Producer Consumer Problem:
class Q {
int val;
boolean flag=false;
synchronized int get()
{
if(!flag)
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Consumer consuming "+val);
flag=false;
notify();
return val;
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 22


synchronized void put(int val)
{
if(flag)
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
this.val=val;
flag=true;
System.out.println("Producer Producing "+val);
notify();
}
}
class producer extends Thread
{
Q obj;
producer(Q t)
{
obj=t;

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 23


}
public void run()
{
for(int i=0;i<10;i++)
{
obj.put(i);
}
}
}
class consumer extends Thread
{
Q obj1;
consumer(Q t)
{
obj1=t;
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 24


public void run()
{
for(int i=0;i<10;i++)
{
obj1.get();
}
}
}
public class PC {
public static void main(String[] args) {
Q q = new Q();
producer p=new producer(q);
consumer c=new consumer(q);
p.start();
c.start();
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 25


Output:-
Producer producing: 0
Consumer consuming: 0
Producer producing: 1
Consumer consuming: 1
Producer producing: 2
Consumer consuming: 2
Producer producing: 3
Consumer consuming: 3
Producer producing: 4
Consumer consuming: 4
Producer producing: 5
Consumer consuming: 5
Producer producing: 6
Consumer consuming: 6
Producer producing: 7
Consumer consuming: 7
Producer producing: 8
Consumer consuming: 8
Producer producing: 9
Consumer consuming: 9
Producer producing: 10
Consumer consuming: 10

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 26


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 is achieved is called
synchronization.
• Key to synchronization is the concept called monitor (also called a
semaphore).
• Only one thread can own a monitor at a given time.
• All other threads attempting to enter the locked monitor will be
suspended until the first thread exits the monitor

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 27


Usage of Synchronization
• Synchronized Methods
• Synchronized Keyword

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 28


Synchronized Methods
synchronized return_type function_name (Parameters)
{
//statements
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 29


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.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 30


package pack;
//Producer Consumer Problem: using synchronized keyword
class Q {
int val;
boolean flag=false;
int get()
{
if(!flag)
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Consumer consuming "+val);
flag=false;
notify();
return val;
}
void put(int val)

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 31


{
if(flag)
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
this.val=val;
flag=true;
System.out.println("Producer Producing "+val);
notify();
}
}
class producer extends Thread
{
Q obj;
producer(Q t)
{
obj=t;
12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 32
}
public void run()
{
synchronized(obj) {
for(int i=0;i<10;i++)
{
obj.put(i);
}
}}
}
class consumer extends Thread
{
Q obj1;
consumer(Q t)
{
obj1=t;
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 33


public void run()
{
synchronized(obj1) {
for(int i=0;i<10;i++)
{
obj1.get();
}}
}
}
public class PC {
public static void main(String[] args) {
Q q = new Q();
producer p=new producer(q);
consumer c=new consumer(q);
p.start();
c.start();
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 34


Deadlock in Java

Deadlock in Java is a part of multithreading. Deadlock can occur in a


situation when a thread is waiting for an object lock, that is acquired
by another thread and second thread is waiting for an object lock that
is acquired by first thread. Since, both threads are waiting for each
other to release the lock, the condition is called deadlock.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 35


public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();

public static void main(String args[]) {


ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 36


private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");

try { Thread.sleep(10); }
catch (InterruptedException e) {System.out.println(“Exception raised");
}
System.out.println("Thread 1: Waiting for lock 2...");

synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 37


private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");

try {
Thread.sleep(10);
}
catch (InterruptedException e) {
System.out.println(“Exception raised");
}

System.out.println("Thread 2: Waiting for lock 1...");

synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 38


Suspending, Resuming, and Stopping Threads
• final void suspend( )
• final void resume( )

suspend( ) and resume( ), which are methods defined by Thread, to


pause and restart the execution of a thread.

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 39


import java.io.*;
public class Main extends Thread {
public void run()
{
try {
//print the current thread
System.out.println("Current thread is thread number " +
Thread.currentThread().getName());
}
catch (Exception e) {
System.out.println(e);
}
}
12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 40
public static void main(String[] args) {

//1 thread created


Main t1=new Main();

//running the threads


t1.start();

//putting it to sleep for 300ms


t1.sleep(300);

//now suspend the thread


t1.suspend();
System.out.println("Thread is suspended");

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 41


//resume the thread
t1.resume();

System.out.println("Thread is Resumed");
try {
t1.join();
}
catch(Exception e)
{
System.out.println(e);
}

}
}

12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 42


12/2/2024 Prof. Masooda, Dept. of ISE, SCEM 43

You might also like