KEMBAR78
Unit 7 - Threads | PDF | Thread (Computing) | Process (Computing)
0% found this document useful (0 votes)
5 views14 pages

Unit 7 - Threads

This document provides an overview of multithreading in Java, explaining its features, thread states, and methods for creating threads using the Thread class and Runnable interface. It also covers thread management concepts such as stopping, blocking, priorities, synchronization, inter-thread communication, and deadlock. Various code examples illustrate these concepts, demonstrating how threads can run concurrently and the importance of managing shared resources.

Uploaded by

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

Unit 7 - Threads

This document provides an overview of multithreading in Java, explaining its features, thread states, and methods for creating threads using the Thread class and Runnable interface. It also covers thread management concepts such as stopping, blocking, priorities, synchronization, inter-thread communication, and deadlock. Various code examples illustrate these concepts, demonstrating how threads can run concurrently and the importance of managing shared resources.

Uploaded by

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

Unit – 7 Threads [3 Hrs.

]
Multithreading is a Java feature that allows concurrent execution of two or more parts of a
program for maximum utilization of CPU. Each part of such program is called a thread. So,
threads are light-weight processes within a process.
A thread is actually a lightweight process. Unlike many other computer languages, 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 the execution. Thus, multithreading is a specialized form of
multitasking.

The Java Thread Model


The Java run-time system depends on threads for many things. Threads reduce inefficiency by
preventing the waste of CPU cycles.
Threads exist in several states:
• New - When we create an instance of Thread class, a thread is in a new state.
• Running - The Java thread is in running state.
• Suspended - A running thread can be suspended, which temporarily suspends its activity.
A suspended thread can then be resumed, allowing it to pick up where it left off.
• Blocked - A Java thread can be blocked when waiting for a resource.
• Terminated - A thread can be terminated, which halts its execution immediately at any
given time. Once a thread is terminated, it cannot be resumed.

Threads can be created by using two mechanisms:


1. Extending the Thread class
2. Implementing the Runnable Interface
Thread creation by extending the Thread class

We create a class that extends the java.lang.Thread class. This class overrides the run() method
available in the Thread class. A thread begins its life inside run() method. We create an object of
our new class and call start() method to start the execution of a thread. Start() invokes the run()
method on the Thread object.

public class MyClass extends Thread {


public void run(){
System.out.println("MyClass running");
}
}

To create and start the above thread:

MyClass t1 = new MyClass ();


t1.start();
//or
//new MyClass().start();

Example Program:

class ThreadA extends Thread{


public void run() {
for(int i=1;i<=5;i++) {
System.out.println("Running thread "+i+" From Class A");
}
System.out.println("Exit from Class A");
}
}

class ThreadB extends Thread{


public void run() {
for(int j=1;j<=5;j++) {
System.out.println("Running thread "+j+" From Class B");
}
System.out.println("Exit from Class B");
}
}
class ThreadC extends Thread{
public void run() {
for(int k=1;k<=5;k++) {
System.out.println("Running thread "+k+" From Class C");
}
System.out.println("Exit from Class C");
}
}

public class ThreadExample {


public static void main(String[] args) {
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}

Output
Running thread 1 From Class A
Running thread 2 From Class A
Running thread 3 From Class A
Running thread 4 From Class A
Running thread 5 From Class A Exit
from Class A
Running thread 1 From Class B
Running thread 2 From Class B
Running thread 3 From Class B
Running thread 4 From Class B
Running thread 5 From Class B
Exit from Class B
Running thread 1 From Class C
Running thread 2 From Class C
Running thread 3 From Class C
Running thread 4 From Class C
Running thread 5 From Class C
Exit from Class C

We have simply initiated three new threads and started them. They are running concurrently on
their own. Note that the output from the threads is not specially sequential. They do not follow
any specific order. They are running independently of one another and each executes whenever
it has a chance. Remember, once the threads are started, we cannot decide with certainty the
order in which they may execute statements.
Thread creation by implementing the Runnable Interface
The easiest way to create a thread is to create a class
that implements the Runnable interface.
To implement Runnable interface, a class need only implement a single method called run(),
which is declared like this:

public class MyClass implements Runnable


{
public void run()
{
System.out.println("MyClass running");
}
}

To execute the run() method by a thread, pass an instance of MyClass to a Thread in its
constructor. Here is how that is done:

//MyClass obj=new MyClass();


//Thread t1=new Thread(obj);
//t1.start();
//or
Thread t1 = new Thread(new MyClass());
t1.start();

Example Program

class ThreadA implements Runnable


{
public void run()
{
for(int i=1;i<=5;i++) {
System.out.println("Running thread "+i+" From Class A");
}
System.out.println("Exit from Class A");
}
}
class ThreadB implements Runnable
{
public void run()
{
for(int j=1;j<=5;j++)
{
System.out.println("Running thread "+j+" From Class B");
}
System.out.println("Exit from Class B");
}
}

class ThreadC implements Runnable


{
public void run()
{
for(int k=1;k<=5;k++) {
System.out.println("Running thread "+k+" From Class C");
}
System.out.println("Exit from Class C");
}
}

public class ThreadExample {


public static void main(String[] args)
{
Thread t1=new Thread(new ThreadA());
Thread t2=new Thread(new
ThreadB());
Thread t3=new Thread(new ThreadC());
t1.start();
t2.start();
t3.start();
}
}

Output
Running thread 1 From Class B
Running thread 1 From Class C
Running thread 2 From Class C
Running thread 3 From Class C
Running thread 4 From Class C
Running thread 5 From Class C
Running thread 1 From Class A
Running thread 2 From Class A Exit
from Class C
Running thread 2 From Class B
Running thread 3 From Class A
Running thread 4 From Class A
Running thread 5 From Class A
Exit from Class A
Running thread 3 From Class B
Running thread 4 From Class B
Running thread 5 From Class B
Exit from Class B

Note: Output can be different on each run because thread doesn’t follow sequential order.

Stopping and Blocking a Thread


Stopping a Thread
Whenever we want to stop a thread from running further, we may do so by calling stop()
method, like:
aThread.stop();
This statement causes the thread to move to the dead state. A thread will also move to the dead
state automatically when it reaches the end of its method. The stop() method may be used when
the premature death of a thread is desired.

Blocking a Thread
A thread can also be temporarily suspended or blocked from entering into the runnable state by
using either of the following thread methods:
sleep()
//blocked for a specified time suspend()
// blocked until further orders wait()
//blocked until certain condition orders

//Program to demonstrate stop() and sleep().


class ThreadA extends Thread {
public void run() {
for(int i=1;i<=5;i++) {
System.out.println("Running thread "+i+" From Class A");
if(i==3) stop();
}
System.out.println("Exit from Class A");
}
}
class ThreadB extends Thread {
public void run() {
for(int j=1;j<=5;j++) {
System.out.println("Running thread "+j+" From Class B");
if(j==2)
try {
sleep(1000); //in milliseconds
//sleep must be surrounded with try/catch
} catch (Exception e) {
System.out.println(e);
}
}
System.out.println("Exit from Class B");
}
}

class ThreadC extends Thread {


public void run() {
for(int k=1;k<=5;k++) {
System.out.println("Running thread "+k+" From Class C");
}
System.out.println("Exit from Class C");
}
}

public class ThreadExample {


public static void main(String[] args) {
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}

Output
Running thread 1 From Class A
Running thread 2 From Class A
Running thread 3 From Class A
Running thread 1 From Class B
Running thread 2 From Class B
Running thread 1 From Class C
Running thread 2 From Class C
Running thread 3 From Class C
Running thread 4 From Class C
Running thread 5 From Class C
Exit from Class C
Running thread 3 From Class B
Running thread 4 From Class B
Running thread 5 From Class B
Exit from Class B
Thread Priorities
Thread priorities are used by the thread scheduler to decide when each thread should be allowed
to run. In theory, higher-priority threads get more CPU time than lower-priority threads. In
practice, the amount of CPU time that a thread gets often depends on several factors besides its
priority. (For example, how an operating system implements multitasking can affect the relative
availability of CPU time.) A higher-priority thread can also preempt a lower-priority one. For
instance, when a lower-priority thread is running and a higher-priority thread resumes (from
sleeping or waiting on I/O, for example), it will preempt the lower priority thread.
Java permits us to set the priority of a thread using the setPriority() method as follows:
ThreadName.setPriority (intNumber)

The intNumber is an integer value to which the thread’s priority is set. The Thread class defines
several priority constants:
MIN_PRIORITY = 1
NORM_PRIORITY = 5
MAX_PRIORITY = 10

The intNumber may assume one of these constants or any value between 1 and 10. Note that
the default setting is NORM_PRIORITY.

//Program to demonstrate thread priority.


class ThreadA extends Thread{
public void run() {
for(int i=1;i<=5;i++)
{
System.out.println("Running thread "+i+" From Class A");
}
System.out.println("Exit from Class A");
}
}

class ThreadB extends Thread{


public void run() {
for(int j=1;j<=5;j++) {
System.out.println("Running thread "+j+" From Class B");
}
System.out.println("Exit from Class B");
}
}
class ThreadC extends Thread {
public void run() {
for(int k=1;k<=5;k++) {
System.out.println("Running thread "+k+" From Class C");
}
System.out.println("Exit from Class C");
}
}
public class ThreadExample {
public static void main(String[] args) {
ThreadA t1=new ThreadA();
ThreadB t2=new ThreadB();
ThreadC t3=new ThreadC();

t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(t1.getPriority()+1);

//or t2.getPriority(2)
t3.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}

Note that although the threadA started first, the higher priority threadB has preempted it and
started printing the output first. Immediately, the threadC that has been assigned the highest
priority takes control over the other two threads. The threadA is the last to complete.

Synchronization in Thread
Multi-threaded programs may often come to a situation where multiple threads try to access
the same resources and finally produce erroneous and unforeseen results. So, it needs to be
made sure by some synchronization method that only one thread can access the resource at a
given point of time.
Java provides a way of creating threads and synchronizing their task by using synchronized
blocks. Synchronized blocks in Java are marked with the synchronized keyword. A synchronized
block in Java is synchronized on some object. All synchronized blocks synchronized on the same
object can only have one thread executing inside them at a time. All other threads attempting
to enter the synchronized block are blocked until the thread inside the synchronized block exits
the block.

If you declare any method as synchronized, it is known as synchronized method.


Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object
and releases it when the thread completes its task.

class AThread {

synchronized void deposit(int amt) {


System.out.println("Deposit Completed with Rs. "+amt);
}
synchronized void withdraw(int amt) {
System.out.println("Withdraw Completed with Rs. "+amt);
}
}

public class Synchronization {


public static void main(String[] args) {
AThread obj=new AThread();

new Thread() {
public void run() {
obj.deposit(15000);
}
}.start();

new Thread() {
public void run() {
obj.withdraw(10000);
}
}.start();

}
}

Output
Deposit Completed with Rs. 15000
Withdraw Completed with Rs. 10000
Inter Thread Communication
Inter-thread communication or Co-operation is all about allowing synchronized threads to
communicate with each other.
Cooperation (Inter-thread communication) is a mechanism in which a thread is paused running
in its critical section and another thread is allowed to enter (or lock) in the same critical section
to be executed. It is implemented by following methods of Object class:
o wait()
o notify()
o notifyAll()

1) wait() method
Causes current thread to release the lock and wait until either another thread invokes the
notify() method or the notifyAll() method for this object, or a specified amount of time has
elapsed.

2) notify() method
Wakes up a single thread that is waiting. If any threads are waiting on this object, one of them is
chosen to be awakened.

3) notifyAll() method
Wakes up all threads that are waiting.

class AThread {
int amount=10000;
synchronized void withdraw(int amt) {
System.out.println("Going to Withdraw...");
if(amount<amt) {
System.out.println("Less balance; waiting for deposit...");
try {
wait();
} catch (Exception e) {
System.out.println(e);
}
}
amount-=amt;
System.out.println("Withdraw Completed with Rs. "+amt);
System.out.println("Balance is Rs. "+amount);
}

synchronized void deposit(int amt) {


System.out.println("Going to Deposit...");
amount+=amt;
System.out.println("Deposit Completed with Rs. "+amt);
System.out.println("Balance is Rs. "+amount);
notify();
}
}

public class Synchronization{


public static void main(String[] args) {
AThread obj=new AThread();

new Thread() {
public void run() {
obj.withdraw(15000);
}
}.start();

new Thread() {
public void run() {
obj.deposit(10000);
}
}.start();
}
}

Output
Going to Withdraw...
Less balance; waiting for deposit...
Going to Deposit...
Deposit Completed with Rs. 10000
Balance is Rs. 20000
Withdraw Completed with Rs. 15000
Balance is Rs. 5000

Deadlock
synchronized keyword is used to make the class or method thread-safe which means only one
thread can have lock of synchronized method and use it, other threads have to wait till the lock
releases and anyone of them acquire that lock.
It is important to use if our program is running in multi-threaded environment where two or
more threads execute simultaneously. But sometimes it also causes a problem which is called
Deadlock. Below is a simple example of Deadlock condition.
Important Points :
• If threads are waiting for each other to finish, then the condition is known as Deadlock.
• Deadlock condition is a complex condition which occurs only in case of multiple threads.
• Deadlock condition can break our code at run time and can destroy business logic.
• We should avoid this condition as much as we can.

class MyThread{
String resource1 = "BCA";
String resource2 = "Third Semester";

void MethodA() {
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");

try {
Thread.sleep(100);
}
catch (Exception e) {}

synchronized (resource2) {
System.out.println("Thread 1: need resource 2");
}
}
}

void MethodB() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try { Thread.sleep(100);} catch (Exception e) {}

synchronized (resource1) {
System.out.println("Thread 2: need resource 1");
}
}
}
}

public class Deadlock {


public static void main(String[] args) {
MyThread obj=new MyThread();
new Thread() {
public void run() {
obj.MethodA();
}
}.start();

new Thread() {
public void run() {
obj.MethodB();
}
}.start();
}
}

Output
Thread 1: locked resource 1
Thread 2: locked resource 2

You might also like