0% found this document useful (0 votes)
26 views16 pages

7.multi Threading Notes

The document discusses multi-threading in Java. It defines single and multi-tasking, and explains that multi-tasking can be achieved through process-based or thread-based multi-tasking. Thread-based multi-tasking in Java is implemented using multi-threading. The document then discusses how to create user-defined threads by extending the Thread class or implementing the Runnable interface. It also covers thread life cycles, states, and methods like start() and run().

Uploaded by

rahul
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
Download as txt, pdf, or txt
0% found this document useful (0 votes)
26 views16 pages

7.multi Threading Notes

The document discusses multi-threading in Java. It defines single and multi-tasking, and explains that multi-tasking can be achieved through process-based or thread-based multi-tasking. Thread-based multi-tasking in Java is implemented using multi-threading. The document then discusses how to create user-defined threads by extending the Thread class or implementing the Runnable interface. It also covers thread life cycles, states, and methods like start() and run().

Uploaded by

rahul
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1/ 16

==============

Multi Threading
==============

Task : Work

Single Tasking : Performing only one task at a time is called as Single Tasking

Ex:

1) Explain the topic


2) Dictate the notes
3) Ask questions

-> If we perform single tasking then it will take lot of time to complete all our
work.

Multi Tasking : Performing multiple tasks at a time is called as Multi Tasking

Ex:

1) Walking & listening music

2) Speaking and Writing

3) Reading book & eating

-> If we perform multi tasking then we complete multiple works at a time.

-> Multi Tasking we can achieve in 2 ways

1) Process Based Multi Tasking

Ex: Windows OS

2) Thread Based Multi Tasking

-> To execute our program logics paralelly then we need to go for Thread Based
Multi Tasking

-> Using Thread Based Multi Tasking our program can complete the work quickly

-> To implement Thread Based Multi Tasking we will use Multi Threading

-> Java Supports Multi Threading

=============================
Use case to go for Multi Threading
=============================

1) Send sms to all customers at a time


2) Send Email to all customers at a time
3) Generate & Send Bank Statements to all customers in email

Note: The main aim of Multi Tasking is used execute our program logic paralelly so
that we can complete more work in less time.
-> For Every Java program execution, JVM will create one thread by default. That
thread is called as Main thread.

// Java Program to get the details of Main thread

public class Demo {

public static void main(String... args) {

Thread currentThread = Thread.currentThread();


System.out.println(currentThread.getName()); // main

}
}

Note: Thread is a predefined class available in java.lang package. In Thread class


we have a static method currentThread ( ).

===================
User Defined Threads
===================

-> In Java we can create Thread in 2 ways

1) By extending Thread class

2) By Implementing Runnable interface

// Java program to create user defined thread using Thread class

public class Demo extends Thread {

public void run() {


System.out.println("run () method called...");
}

public static void main(String... args) {

Demo d = new Demo();

Thread t = new Thread(d);


t.start();
}
}

// Java program to create the thread using Runnable interface

public class Demo implements Runnable {

public void run() {


System.out.println("run () method called...");
}

public static void main(String... args) {


Demo d = new Demo();

Thread t = new Thread(d);


t.start();
}
}

===================================================================================
===============
Q) What is the difference between extending Thread class and implementing Runnable
interface, which is recommended ?
===================================================================================
===============

-> If we extend properties from Thread class then we can't extend properties from
any other class because java doesn't support mulitple inheritence. (We are closing
gate for Inheritence)

-> If we implement Runnable interface then in future we can extend properties from
any class based on requirement. (Our gate is open for inheritence)

Note: Implementing Runnable interface is always recommended.

=======================
What is Thread Schedular
=======================

-> Thread Schedular is a program in the JVM which is responsible to schedule


Threads execution and resources allocation required for the thread.

-> When we call start ( ) method then Thread Schedular will start its operation.

1) Allocating Resources

2) Thread Scheduling

3) Thread Execution by calling run ( ) method

================================
start ( ) method vs run ( ) method
================================

-> To start thread execution we will call start ( ) method

t.start ( )

-> once start ( ) method is called then Thread Schedular will come into picture to
execute our thread

-> start ( ) method will call run ( ) method internally

-> inside run ( ) method we will write the logic which should be executed by the
thread.

=======================================================
Can we call run ( ) method directley without calling start ( ) method
========================================================

-> Yes, we can call run ( ) method directley but it will execute like a normal
method (there is no use) by "main" thread.

-> If we want to execute run ( ) method as a thread method then we should call
start ( ) method then internally it will call run ( ) method (Thread Schedular will
take care of thread execution)

public class Demo implements Runnable {

public void run() {


System.out.println("run () method started...");

Thread t = Thread.currentThread();
System.out.println(t.getName());

System.out.println("run () method ended...");


}

public static void main(String... args) {


Demo d = new Demo();

Thread t = new Thread(d);


//t.start();
// t.run();
}
}

=> If we call start ( ) method then run ( ) method will be executed by our user
defined thread (we can see thread name as Thread-0)

=> if we call run ( ) method then run ( ) method will be executed by "main" thread
(we can see thread name as main)

======================
What is Thread Life Cycle
======================

-> Thread Life cycle contains several phases of Thread execution

1) New

2) Runnable

3) Running

4) Blocked

5) Terminated

New: A thread begins its life cycle in the new state. Thread remains in the new
state until we will call start ( ) method.
Runnable : After calling start ( ) method, thread comes from new state to runnable
state.

Running : A thread comes to running state when Thread Schedular will pick up that
thread for execution.

Blocked : A thread is in waiting state if it waits for another thread to complete


its task.

Terminated : A thread enters into terminated state once it completes its task.

// Java Program on Thread Sleep

package in.ashokit;

public class Demo implements Runnable {

public void run() {


System.out.println("run () method started...");

try {
Thread.sleep(5000); // blocked state
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("run () method ended...");


}

public static void main(String... args) {


Demo d = new Demo();

Thread t = new Thread(d); // new state


t.start(); // runnable state
}
}

// Java program to start mutliple threads to perform same activity

package in.ashokit;

public class Demo implements Runnable {

public void run() {


System.out.println("run () method started..." +
Thread.currentThread().getName());
try {
Thread.sleep(15000); // blocked state
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run () method ended..." +
Thread.currentThread().getName());
}
public static void main(String... args) {
Demo d = new Demo();

Thread t1 = new Thread(d);


t1.setPriority(Thread.MAX_PRIORITY); // 10
t1.setName("Thread-1");

Thread t2 = new Thread(d);


t2.setPriority(Thread.NORM_PRIORITY); // 5
t2.setName("Thread-2");

Thread t3 = new Thread(d);


t3.setPriority(Thread.MIN_PRIORITY); // 1
t3.setName("Thread-3");

t1.start(); // runnable state


t2.start(); // runnable state
t3.start(); // runnable state
}
}

Note: We shouldn't start one thread more than one time.

public static void main(String... args) {


Demo d = new Demo();

Thread t1 = new Thread(d);

t1.start();
t1.start(); // java.lang.IllegalThreadStateException
}

=================
Callable Interface
=================

-> This interface introduced in java 1.5

-> Using Callable interface also we can create the Thread

-> This interface contains call ( ) method.

Syntax:

public Object call ( )

====================================================
What is the difference between Runnable & Callable interfaces
====================================================

-> Runnable is a functional interface which contains run ( ) method


-> Callable is a functional interface which contains call ( ) method

-> Runnable run ( ) method returns void (no return type)


-> Callable call ( ) method returns Object

-> Runnable interface present in java.lang package


-> Callable interface present in java.util.concurent package

==============================
ExecutorService
==============================

-> Executor Service introduced in java 1.5v

-> Using ExecutorService we can implement multi threading

-> Using Executors we can create thread pool

-> Using Executor Service we can submit tasks to pool of threads.

-> ExecutorService will re-use threads available in the pool to complete all
submitted tasks.

// Java Program on Executor Service with Callable interface

package in.ashokit;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Demo implements Callable {

public Object call() throws Exception {


System.out.println("call ( ) - method executed...");
return "success";
}

public static void main(String[] args) throws Exception {


Demo d = new Demo();

ExecutorService exService = Executors.newFixedThreadPool(10);

for (int i = 1; i <= 15; i++) {


Future submit = exService.submit(d);
System.out.println(submit.get().toString());
}
exService.shutdown();
}
}

=============
Daemon Thread
=============

We have 3 types of threads in java

1) Default thread created by JVM ( main thread )

2) User Defined Threads ( Thread class, Runnable interface, Callable interface )


3) Daemon Threads

Note: The thread which runs in the background is called as Dameon Thread. Daemon
Threads also called as low priority threads.

Ex: Garbage Collector is a daemon thread

-> We can make our thread as Daemon Thread using setDaemon( ) method

// Java Program To Make thread as Daemon

package in.ashokit;

public class Demo implements Runnable {

@Override
public void run() {

if (Thread.currentThread().isDaemon()) {
System.out.println("Daemon Thread Executed...");
} else {
System.out.println("Normal Thread Executed...");
}

public static void main(String[] args) {


Demo d = new Demo();
Thread t1 = new Thread(d);
t1.setDaemon(true);
t1.start();
}
}

-> When JVM reaches end of main method, it will terminate our program. If JVM
founds Daemon thread running it terminates that daemon thread and then it will
shutdown the program.

-> JVM will not care about Daemon Threads running status to stop the program
execution.

==============
Synchronization
==============

String ----> Immutable class

StringBuffer ----> Mutable class & synchronized class (Thread safe class)

StringBuilder ---> Mutable class & not-synchronized class (Not Thread Safe class)

Synchronized means Thread safe ===> Only one thread can access the object /
resource at a time

Not-Synchronized means Not Thread Safe => Multiple threads can access same
resource / object at a time

public class MovieTicketBooking {

int avilableTickets = 100;

public void run ( ) {


if ( availableTickets > 0 ) {
// logic to bookTicket;
-- avilableTickets ;
}
}

psvm ( ) {
Thread t1 = new Thread();
Thread t2 = new Thread();
Threa t20 = new Thread();

t1..... t20 ---start


}
}

-> In the program, multiple threads are trying to book tickets at a time

Note: If multiple threads access the same object at a time then there is a chance
of getting data inconsistency problem.

=> To avoid data inconsistency problem, we need to use Synchronization concept

=> Synchronization means allowing only one thread to execute our resource /
object / logic at a time

Note: By Using Synchronization we can achieve Thread Safety but it will slow down
our execution process.

===========================
How to achieve synchronization
===========================

-> Using 'synchronized' keyword we can implement synchronization

-> synchronized keyword we can use at two places

1) At method level

2) At block level

--------------------------------------------
Syntax For Synchronized Block:
--------------------------------------------

public void m1( ){


// pre-logic

synchronized ( object ) {
// imp business logic
}

// post-logic

--------------------------------------------
Syntax For Synchronized Method :
--------------------------------------------

public synchronized void m1( ) {

// important business logic

// Java Program with Synchronized Method

public class Demo implements Runnable {

public synchronized void printNums() {


for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + "=> " + i);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}

public void run() {


printNums();
}

public static void main(String[] args) {


Demo d = new Demo();

Thread t1 = new Thread(d);


t1.setName("Thread-1");
t1.start();

Thread t2 = new Thread(d);


t2.setName("Thread-2");
t2.start();
}
}

Note: In the above program we are starting 2 threads. two threads will access
printNums ( ) method to print the numbers from 1 to 10.

-> If printNums ( ) method having synchronized keyword then two threads will
execute the method sequentially one after other .

-> if we remove synchronized keyword from the printNums ( ) method then two threads
will access that method at a time.

Note: We can see the difference in the output.

==============================================
Working with Threads using Anonymous Implementation
==============================================

package in.ashokit;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyThread {

public static void main(String[] args) {

Thread t1 = new Thread() {


public void run() {
System.out.println("run ( ) method logic-1");
}
};
t1.start();

Runnable r = new Runnable() {


@Override
public void run() {
System.out.println("run method() logic-2");
}
};

Thread t2 = new Thread(r);


t2.start();

Callable c = new Callable() {


public Object call() throws Exception {
System.out.println("call( ) method logic - 3");
return null;
}
};

ExecutorService exService = Executors.newFixedThreadPool(1);


exService.submit(c);
}
}

==========
Dead Lock
=========

-> Dead Lock means ambiguity problem among the threads

-> If 2 threads are waiting for each other to release the resources is called as
dead lock.

-> Once we get into dead lock situation then we can't do anything

Ex:
----

Thread-1 holding resource-1 and waiting for resource-2

Thread-2 holding resource-2 and waiting for resource-1

Note:

Thread-1 will not release resource-1 hence thread-2 will be in waiting state
forever for resource-1

Thread-2 will not release resource-2 hence thread-1 will be in waiting state
forever for resource-2

// Java program which will give dead lock

package in.ashokit;

public class DeadLock {

public static void main(String[] args) {

String s1 = "hi";
String s2 = "hello";

Thread t1 = new Thread() {


public void run() {
synchronized (s1) {
System.out.println("Thread-1 locked resource-1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2) {
System.out.println("Thread-1 waiting for
resource-2");
}
}
}
};

Thread t2 = new Thread() {


public void run() {
synchronized (s2) {
System.out.println("Thread-2 locked resource-2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s1) {
System.out.println("Thread-2 waiting for
resource-1");
}
}
}
};
t1.start();
t2.start();
}
}

=============
join ( ) method
=============

-> join ( ) method is used to hold second thread execution until first thread
execution got completed

package in.ashokit;

public class Demo {

public static void main(String[] args) throws Exception {

Thread t1 = new Thread() {


public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() +
" => " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t1.setName("Thread-1");

Thread t2 = new Thread() {


public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() +
" => " + i);
try {
Thread.sleep(100);
Thread.yield();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t2.setName("Thread-2");

t1.start();
t1.join();
t2.start();
}
}

==============
yield ( ) method
===============

-> yield ( ) method is used to give chance for other equal priority threads to
execute

// Java program with yield ( ) method

package in.ashokit;

public class YieldDemo {

public static void main(String[] args) {


Thread producer = new Producer();
Thread consumer = new Consumer();

producer.start();
consumer.start();
}
}

class Producer extends Thread {


public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("Producer : Produced Item " + i);
Thread.yield();
}
}
}

class Consumer extends Thread {


public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("Consumer : Consumed Item " + i);
Thread.yield();
}
}
}

========================
Inter Thread Communication
========================

-> It is used to establish communication among the threads

-> To achieve inter thread communication we have below 3 methods in Object class

1) wait ( )
2) notify ( )
3) notifyAll ( )

Q) Why these 3 methods available in Object class, why not in Thread class ?

-> If these methods available in Thread class then we have to extend Thread class.
In future we can't extend from any other java class bcz java is against for
Multiple Inheritence.

-> If these methods available in Runnable interface then everybody should implement
these method even if they don't need inter thread communication.

-> To overcome all these problems, java kept these methods in Object class so that
every class will have access for these methods.

// Java Program to establish inter thread communication

package in.ashokit;

public 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) {


System.out.println("going to deposit...");
this.amount += amount;
System.out.println("deposit completed... ");
notify();
}

public static void main(String args[]) {


final Customer c = new Customer();

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

try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread() {
public void run() {
c.deposit(10000);
}
}.start();
}
}

================================
Multi Threading Summary
=================================
1) What is Multi Tasking
2) What is Multi Threading
3) Advantages of Multi Threading
4) Default Thread in JVM (main)
5) Getting info of main thread ( Thread.currentThread( ) )
6) Creating User Defined Threads
7) By Extending Thread class
8) By Implementing Runnable interface
9) By implementing Callable interface
10) run ( ) method vs call ( )
11) Executor Service
12) run ( ) vs start ( ) method
13) Thread Life Cycle
14) Thread Schedular
15) Synchronization (method & block)
16) What is Thread Safety
17) Thread creation with Anonymous implementation
18) Dead Lock (Java Program to give dead lock)
19) join ( ) method vs yield ( ) method
20) Inter Thread Communication
21) Daemon Threads

You might also like