Professional Documents
Culture Documents
Multithreading_Clsasroom_Notes
Multithreading_Clsasroom_Notes
Multithreading_Clsasroom_Notes
-----------------
Q)What is the difference between Process, Procedure and Processor?
-------------------------------------------------------------------
Ans:
-----
Procedure is a set of isntructions representing a particular action.
Thread is flow of execution, it is light weight, it will take less execution time,
it will increase application execution time.
Note: Now a days Majority of the technologies are designed on the basis of Threads.
To prepare Threads, JAVA has provided predefined library in the form of java.lang
package.
1. Thread
2. Runnable
Q)What is Thread and in how many ways we are able to create threads in Java
applications?
--------------------------------------------------------------------------
Ans:
-----
Thread is flow of execution to perform a particular task.
As per the predefined library provided by Java, there are two ways to create
threads.
Note: It will create new thread[Flow of execution] and it will send that
thread to run() method to execute.
EX:
---
package com.durgasoft.app01.test;
In GUI Appl.
class MyClass extends Frame{
}
In Java appl.
class MyClass extends Frame , Thread{
}
Single sub class is extended from more than one super class directly, ity
represents Multiple Inhertitance, it is not supported in Java.
To overcome the above problem, we have to use Second Approach tocreate threads.
class Test{
public static void main(String[] args){
Case-1:
MyThread mt = new MyThread();
mt.start();
Status: Compilation Error
Case-2:
MyThread mt = new MyThread();
mt.run();
Status: Here User Thread is not created, only Main Thread is
executing MyThread class run() and main() method, here no Multi Threadding.
Case-3:
MyThread mt = new MyThread();
Thread t = new Thread();
t.start();
Status: Here New Thread is created and it will be submitted to
Thread class run() method, but not, MyThread class run() method.
case-4:
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
Status: Valid, Here new Thread is created and it will be
submitted to MyThread class run() method.
}
}
EX:
---
package com.durgasoft.app01.test;
class WelcomeThread implements Runnable{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("Welcome Thread : "+i);
}
}
}
public class Test {
public static void main(String[] args) {
/*
WelcomeThread welcomeThread = new WelcomeThread();
welcomeThread.start();
*/
/*
WelcomeThread welThread = new WelcomeThread();
welThread.run();
for(int i = 0; i < 10; i++) {
System.out.println("Main Thread : "+i);
}
*/
/*
WelcomeThread wt = new WelcomeThread();
Thread t = new Thread();
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("Main Thread : "+i);
}
*/
WelcomeThread wt = new WelcomeThread();
Thread t = new Thread(wt);
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("Main Thread : "+i);
}
}
}
Thread Lifecycle:
-------------------
It is the collective information of the threads right from its starting point to
ending Point.
In Java applications, Threads are having the following states as part of its
lifecycle.
3. Running State:
-------------------
In Java applications, after accessing start() and after getting system resources
like memory and execution time , this state is called as "Running State".
4. Blocked State:
------------------
To keep a running thread into Blocked state
a)Access sleep() method with a particular sleep time.
b)Access suspend() method over running thread.
c)Access wait() method over running thread.
d)When we perform IO Operations.
Note: If we want to keep a running thread to Ready / Runnable state directly then
we have to use yield() method, it is not supported in Windows Operating system,
because, it required priority based manipulations, Widows OS is not supporting
Priority based Manipulations.
EX:
---
package com.durgasoft.app01.test;
public class Test {
public static void main(String[] args) {
Thread t = new Thread();
System.out.println(t);//Thread[Thread-0,5,main]
}
}
EX:
---
package com.durgasoft.app01.test;
class HelloThread implements Runnable{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("HelloThread : "+i);
}
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new HelloThread();
Thread t = new Thread(r);
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("MainThread : "+i);
}
}
}
EX:
---
package com.durgasoft.app01.test;
class HelloThread implements Runnable{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("HelloThread : "+i);
}
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new HelloThread();
Thread t = new Thread(r);
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("MainThread : "+i);
}
}
}
EX:
----
package com.durgasoft.app01.test;
class WelcomeThread implements Runnable{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("WelcomeThread : "+i);
}
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new WelcomeThread();
ThreadGroup threadGroup = new ThreadGroup("Java");
Thread t = new Thread(threadGroup, r);
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("MainThread : "+i);
}
}
}
EX:
----
package com.durgasoft.app01.test;
class WelcomeThread implements Runnable{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("WelcomeThread : "+i);
}
}
}
public class Test {
public static void main(String[] args) {
Runnable r = new WelcomeThread();
ThreadGroup threadGroup = new ThreadGroup("Java");
Thread t = new Thread(threadGroup,r,"Core Java");
t.start();
for(int i = 0; i < 10; i++) {
System.out.println("MianThread : "+i);
}
}
}
EX:
----
package com.durgasoft.app01.test;
public class Test {
public static void main(String[] args) {
Thread t = new Thread();
System.out.println(t.getName());//Thread-0
t.setName("Core Java");
System.out.println(t.getName());//Core Java
}
}
Note: In Java applications, every thread will have a particular priority value and
that priority values must be from 1 to 10. In the case of setPriority() method we
must provide the priorityValue inbetween 1 and 10, if we provide priorityValu in
out side of 1 to 10 range then JVM will raise an Exception like
"java.lang.IllegalArgumentException".
}
}
EX:
----
package com.durgasoft.app01.test;
public class Test {
public static void main(String[] args) {
Thread t = new Thread();
System.out.println(t.getPriority());
//t.setPriority(15);-->IllegalArgumentException
//t.setPriority(-10);->IllegalArgumentException
//t.setPriority(0);-->IllegalArgumentException
System.out.println(t.getPriority());
}
}
EX:
---
package com.durgasoft.app01.test;
public class Test {
public static void main(String[] args) {
System.out.println(Thread.activeCount());//1
Thread t1 = new Thread();
t1.start();
System.out.println(Thread.activeCount());//<=2
Thread t2 = new Thread();
t2.start();
System.out.println(Thread.activeCount());//<=3
Thread t3 = new Thread();
t3.start();
System.out.println(Thread.activeCount());//<=4
}
}
Note: In Java applications, when we create Thread class object then the generated
Thread is not in active, when we access start() method over the thread reference
then only the generated thread will be in active.
EX:
----
package com.durgasoft.app01.test;
public class Test {
public static void main(String[] args) {
Thread t = new Thread();
System.out.println(t.isAlive());
t.start();
for(int i = 0; i < 100; i++) {
System.out.println(t.isAlive()+" ");
}
}
}
t1.setName("AAA");
t2.setName("BBB");
t3.setName("CCC");
t1.start();
t2.start();
t3.start();
}
}
EX:
----
package com.durgasoft.app01.test;
class MyThread extends Thread{
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
public class Test {
public static void main(String[] args) {
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
MyThread mt3 = new MyThread();
mt1.setName("AAA");
mt2.setName("BBB");
mt3.setName("CCC");
mt1.start();
mt2.start();
mt3.start();
}
}
8. public static void sleep(ling time)throws InterruptedException
--> It can be used to keep a running thread into sleep state untill the specified
sleep time, if the sleep time is completed then the sleeping thread will come to
active state automatically and continous its execution time.
EX:
---
package com.durgasoft.app01.test;
class WelcomeThread extends Thread{
public void run() {
for(int i = 0;i < 10; i++) {
try {
Thread.sleep(1000);
System.out.println("Welcome To Durgasoft");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test {
public static void main(String[] args) {
WelcomeThread wt = new WelcomeThread();
wt.start();
}
}
Daemon Threads:
---------------
Daemon Thread is a thread running internally and providing services to some other
thread, Damon threads will be terminated automatically when the threads which are
taking services from daemon threads are terminated.
EX: Garbage Collector inside JVM is Daemon Thread.
In Java applications, to make a thread as daemon thread we must use the following
method.
EX:
---
package com.durgasoft.app01.test;
gc.start();
gc.setDaemon(true);
for(int i = 0; i < 10; i++) {
System.out.println("JVM Thread");
}
System.out.println(gc.isDaemon());
}
}
Concurrent Threads:
--------------------
In Multi Threadding, we may create more than one thread and we may execute more
than one thread at a time.
If we execute more than one thread on single data item or on single program then
that threads are called as "Concurrent Threads" and that process is called as
"Threads Concurrency".
In the case of Threads concurrncy there may be chances are available to get Data
Inconsistency, it will provide wrong results in Java applications.
If any resource allows more than one thread at a time with out providing data
inconsistency then that resource is called as "Threadsafe Resource".
If any thread access the local variable of a method then the respective local
variable value will be stored in the threads respective stack only.
If multiple threads access the same local variable then multiple copies of the
respective local variable will be stored in threads respective stacks.
If we declare any non static variable at class level then that variable is called
as an instance variable.
In java applications, instance variables data will be stored inside the objects in
heap memory.
In general, Heap memory objects are shared objects for multiple threads, all the
threads can access data, it may provide data inconsistency.
EX:
----
package com.durgasoft.app01.test;
class A{
int i = 10;
void increment() {
i = i + 10;
System.out.println(Thread.currentThread()+" : "+i);
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
public class Test {
public static void main(String[] args){
A a = new A();
Thread1 t1 = new Thread1(a);
Thread2 t2 = new Thread2(a);
t1.start();
t2.start();
}
}
EX:
----
package com.durgasoft.app01.test;
class A{
void increment() {
int i = 10;
i = i + 10;
System.out.println(Thread.currentThread().getName()+" : "+i);
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
public class Test {
public static void main(String[] args){
A a = new A();
Thread1 t1 = new Thread1(a);
Thread2 t2 = new Thread2(a);
t1.setName("Thread-1");
t2.setName("Thread-2");
t1.start();
t2.start();
}
}
EX:
---
package com.durgasoft.app01.test;
class A{
int i = 10;
void increment() {
int j = 10;
i = i + 10;
j = j + 10;
System.out.println(Thread.currentThread().getName()+" : Instance
Variable : "+i);
System.out.println(Thread.currentThread().getName()+" : Local Variable
: "+j);
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.increment();
}
}
public class Test {
public static void main(String[] args){
A a = new A();
t1.setName("Thread-1");
t2.setName("Thread-2");
t1.start();
t2.start();
}
}
class A{
StringBuffer sb = new StringBuffer("Durga");
void add() {
sb = sb.append("soft");
System.out.println(Thread.currentThread()+" : "+sb);
}
}
Immutable Objects are normal Java objects, they will not allow modifications on
their content, if we are trying to perform modifications on its content then data
is allowed for modifications but the resultent modified data will not be stored
back in original object , where the resultent modified data will be stored by
creating new Object.
EX: String class objects are Immutable objects.
All Wrapper Classes Objects are Immutable.
In Java applications, if we submit more than one thread on single String object
[Immutable Object] and if more than one thread is performing modifications on
single immutable object content, then, at each and every modification a seperate
new String object will be created , where new modified data will be stored, old
Object data is remains same , this approach will not allow overriding one thread
modifications with another thread modifications, this approach will provide data
consistency, it will make the resource as Threadsafe resource.
EX:
---
package com.durgasoft.app01.test;
class A{
String str1 = new String("Durga");
void add() {
String str2 = str1.concat("soft");
System.out.println(Thread.currentThread().getName()+" : "+str2);
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.add();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.add();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
Thread1 t1 = new Thread1(a);
Thread2 t2 = new Thread2(a);
t1.setName("Thread1");
t2.setName("Thread2");
t1.start();
t2.start();
}
}
EX:
----
package com.durgasoft.app01.test;
class A{
String str1 = new String("Durga");
StringBuffer sb1 = new StringBuffer("Durga");
void modify() {
String str2 = str1.concat("soft");
StringBuffer sb2 = sb1.append("soft");
System.out.println("str2 : "+Thread.currentThread().getName()+" :
"+str2);
System.out.println("sb : "+Thread.currentThread().getName()+" :
"+sb2);
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.modify();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.modify();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
Thread1 t1 = new Thread1(a);
Thread2 t2 = new Thread2(a);
t1.setName("Thread-1");
t2.setName("Thread-2");
t1.start();
t2.start();
}
}
3. Use Synchronization:
-----------------------
Synchronization is a mechanism, it able to allow only one thread at a time, it
unable to allow more than one thread at a time, it will allow other threads after
completing the present thread execution.
In general, in Java applications, when we execute more than one thread on single
data item , when we perform modifications on single data item more than one thread
and when one thread modifications are overridden with another thread modifications
there we will get data inconsistency, but, synchronization is allowing only one
thread, there is no scope to override one thread modification with another thread
modifications , there is no scope to get data inconsistency, so synchronization is
always providing data consistency, bydefault, all synchronized resources are
Threadsafe.
Note: Bydefault, all synchronized resources are Threadsafe, but, all Threadsafe
resources need not be synchronized resources, because, we are able to make resource
as Threadsafe resource in multiple ways like by declaring local variables over
instance variables and by using immutable objects over mutable Objects,......
When we submit more than one thread to the synchronized area, where Lock Manager
will assign lock to a particuler thread, here which thread aquire lock from Lock
Manager that thread is eligible to execute synchronized area, when a thread
execution is completed in synchronized area then that thread has to submit lock
back to Lock manager, when Lock Manager gets Lock from a thread from synchronized
area then Lock Manager will assign that lock to another thread which is in waiting
state. If any thread is executing synchronized area then Lock Manager will assign
Lock to other threads.
1. Synchronized Methods
2. Synchronized Blocks
1. Synchronized Methods:
-------------------------
Synchronized Method is a normal java method with 'synchronized' keyword, it allows
only one thread at a time to execute method body, it will not allow more than one
thread at a time to execute method body, after completing the execution of the
present thread only other threads are allowed.
t1.setName("AAA");
t2.setName("BBB");
t3.setName("CCC");
t1.start();
t2.start();
t3.start();
}
}
EX:
----
package com.durgasoft.app01.test;
class A{
synchronized void display() {
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName());
}
}
}
class DisplayThread extends Thread{
A a;
public DisplayThread(A a) {
this.a = a;
}
public void run() {
a.display();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
DisplayThread thread1 = new DisplayThread(a);
DisplayThread thread2 = new DisplayThread(a);
DisplayThread thread3 = new DisplayThread(a);
thread1.setName("Thread-1");
thread2.setName("Thread-2");
thread3.setName("Thread-3");
thread1.start();
thread2.start();
thread3.start();
}
}
2. Synchronized Blocks:
-----------------------
It is a set of instructions, which are able to allow only one thread at a time, it
will not allow more than one thread at a time, after completion of the present
thread execution only other threads are allowed.
Syntax:
-------
synchronized(ObjectToLock){
-------
-------
-------
}
EX:
----
package com.durgasoft.app01.test;
class A{
void display() {
System.out.println("Before Synchronized Block :
"+Thread.currentThread().getName());
synchronized (this) {
for(int i = 0; i < 10; i++) {
System.out.println("Inside Synchronized Block :
"+Thread.currentThread().getName());
}
}
}
}
class Thread1 extends Thread{
A a;
Thread1(A a){
this.a = a;
}
public void run() {
a.display();
}
}
class Thread2 extends Thread{
A a;
Thread2(A a){
this.a = a;
}
public void run() {
a.display();
}
}
class Thread3 extends Thread{
A a;
Thread3(A a){
this.a = a;
}
public void run() {
a.display();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
Thread1 t1 = new Thread1(a);
Thread2 t2 = new Thread2(a);
Thread3 t3 = new Thread3(a);
t1.setName("AAA");
t2.setName("BBB");
t3.setName("CCC");
t1.start();
t2.start();
t3.start();
}
}
Logic:
boolean flag : If its value is true then Producer is Producing an Item
and Consumer must be in waiting state.
If its value is false then Consumer is consuming an item and
Producer must be in waiting state.
If flag == true:
Producer:
Produce an Item
giving tern to Consumer [flag = false].
Giving notification to Consumer
Going to waiting state.
Consumer :
waiting state
If flag == false:
Producer:
waiting state
Consumer :
Consume the item
Giving tern to Producer [flag = true]
Giving Notification to Producer
Going to waiting state
class A{
boolean flag = true;
int count = 0;
Deadlocks:
-----------
--> Deadlock is a situation where more than one thread is depending on
each other in circular dependency.
--> In Java applications, when we get Deadlock , JVM will struck its
execution over the program.
package com.durgasoft.app01.test;
class RegisterCourse extends Thread{
Object courseName;
Object trainerName;
RegisterCourse(Object courseName, Object trainerName){
this.courseName = courseName;
this.trainerName = trainerName;
}
public void run() {
synchronized (courseName) {
System.out.println("RegisterCourse Thread Holds courseName
Rsource and waiting for trainerName");
synchronized (trainerName) {
System.out.println("RegisterCourse Thread Holds both
courseName and trainerName , so that, Course Reistration is Success");
}
}
}
}
class CancelCourse extends Thread{
Object courseName;
Object trainerName;
CancelCourse(Object courseName, Object trainerName){
this.courseName = courseName;
this.trainerName = trainerName;
}
public void run() {
synchronized (trainerName) {
System.out.println("CancelCourse Thread Holds trainerName and
waiting for courseName resource");
synchronized (courseName) {
System.out.println("CancelCourse Thread Holds both
trainerName and courseName, so that, Course Cancellation is Success");
}
}
}
}
public class Test {
public static void main(String[] args) {
Object courseName = new Object();
Object trainerName = new Object();
rc.start();
cc.start();
}
}
ThreadLocal:
------------
In general, in Java applications, there are four types of Scopes for the data.
1. private
2. <default>
3. protected
4. public
Where 'private' scope is able to make available data upto the present class.
Where '<default>' scope is able to make available data upto the present package.
Where 'protected' scope is able to make available data upto the present package and
the chaild class in other packages.
Where 'public' scope is able to make available data through out the application.
Similarily, i want make available data upto all the resources which are accessed by
a particular thread, for this, we have to define a seperate scope for the data that
is 'ThreadScope'.
In Java applications, if we want to define 'ThreaScope' for the Data Java has
provided a predefined class in the form of 'java.lang.ThreadLocal' class.
Where 'ThreadLocal' class has provide the following methods to keep data in
ThreadSCope, To get data from ThreadScope, to remove data from ThreadScope and to
provide default data in ThreadScope.
package com.durgasoft.app01.test;
class ThreadScope extends ThreadLocal<String>{
@Override
protected String initialValue() {
return "Data is not defined in the Scope";
}
}
class A{
void m1() {
System.out.println("m1() : Thread-1 Scope :
"+Thread1.threadScope.get());
System.out.println("m1() : Thread-2 Scope :
"+Thread2.threadScope.get());
}
void m2() {
System.out.println("m2() : Thread-2 Scope :
"+Thread2.threadScope.get());
System.out.println("m2() : Thread-1 Scope :
"+Thread1.threadScope.get());
}
}
class Thread1 extends Thread{
static ThreadScope threadScope = new ThreadScope();
A a;
Thread1(A a){
this.a = a;
}
public void run() {
threadScope.set("AAA");
a.m1();
}
}
class Thread2 extends Thread{
static ThreadScope threadScope = new ThreadScope();
A a;
Thread2(A a){
this.a = a;
}
public void run() {
threadScope.set("BBB");
a.m2();
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
t1.start();
t2.start();
}
}