Sunteți pe pagina 1din 74

Threads

1
Java
Contents

1 Thread in a simple java program


2 Concurrent execution
3 Thread
4 Thread and process
5 Others places where threads play important roles
6 Syntax for creating Thread
7 Complete Example
8 Another way to create thread
9 Behind the scene
10 Naming threads

2
Java
Contents

11 Lifecycle
12 sleep()
13 join()

14 Interruption
15 Thread priorities
16 Selfish threads
17 IllegalArgumentException
18 Synchronization
19 Solution to the Account problem
20 Locking

3
Java
Contents

21 Synchronized Code
22 A few more points !

23 Deadlocks
24 Inter-thread communication
25 Methods of Object class used for thread communication
26 wait() and notify()

27 Daemon threads
28 Challenge your mind

4
Java
Know
• What threads are
• The difference between thread and
process
• How to create threads in java

5
Java
Know
• The Thread life cycle
• The Thread class methods sleep(),
interrupt(), yield() and join() do
• Thread priority
• Synchronization
• Inter-Thread-Communication
• About daemon threads

6
Java
Be Able To
• Implement threads java programs

7
Java
Thread in a simple java program

public class ThreadTest{


public static void main(String s[]){
System.out.println(“Hello”);
System.out.println(
Thread.currentThread().getName());
}}

Prints : main Folder 1

8
Java
Concurrent execution
// include all necessary imports
public class PrintQuestionPaper{

public static void main(String s[]){


for(int i=0;i<5;i++){
Thread no.1
Examination e= new
Examination(“M.C.A”,30);
QuestionPaper q= e.getQuestions(); Concurrent
execution for
better
print(q);} performance
}}
Thread no. 2
public void print(QuestionPaper q){…}}}
9
Java
Thread

• Sun defines a thread as a single


sequential flow of control within a
program.
•It is sometimes referred to as an
execution context or a lightweight process.
• Thread based multitasking environments
allow a single program to perform two or
more tasks simultaneously.

10
Java
Multitasking is multiprocessing

A process is a thread….
I am confused!

OS level Multitasking are of two


types- process based and thread-
based. A process is program that is
executing. Executing multiple
processes simultaneously is
multiprocessing. Process is heavy
weight because it requires separate
address space. Interprocess
communication and context
switching from one process to
another process are expensive.
11
Java
Thread and process
• Threads are the code sequence that execute
within a process.
• So they share the same address space and a
data. Inter-thread communication and context
switching inexpensive.
Threads or a
independent path Process: A
of execution. Java Program

12
Java
I never knew one processor can
execute multiple tasks
simultaneously !

No no ! You don’t get it. One processor


can do only one task at a time. We are
talking about task switching – for example
the task that is waiting for IO to finish can
give up the processor to the to some
other task instead of wasting processor’s
precious time. Of course it ultimately
depends on what kind of threading your
OS supports- Preemptive or Non-
Preemptive .

13
Java
Others places where threads play
important roles
• In client-server based systems, the server
program creates threads that allows it to
respond to multiple users at the same time.
• GUI programs have a separate thread to
gather user’s interface events from the host
OS.
• Do other things while waiting for slow I/O
operation.
• Animations

14
Java
Syntax for creating Thread
or java.lang.Thread
class SimpleThread extends Thread {
public void run(){
1. Inherit from
/* code that is executed when the Thread
class
thread executes */
2. Override run method
}} Creates thread
Calls run() method
Thread t= new SimpleThread();
t.start();
15
Java
class Thread{…
public void start(){
// create OS level thread
run(); }
public void run(){…} 2
}

class SimpleThread {

public void run(){}}
SimpleThread c= new SimpleThread();
c.start();
1
16
Java
(It’s my turn to ask now.)
So, what will happen if you
call run() method instead of
start() method ? Think about
it. If you cannot answer this
now, wait. There is another
hint coming up shortly.

17
Java
Complete Example
class PrimeOddThread extends Thread {
int num;
public void run() {
if( prime())
System.out.println("Prime");
else System.out.println("Non-
Prime");
Folder 2
}
18
Java
public boolean prime(){
for(int i=2;i<num/2;i++){
if(num%i==0) return false;}
return true;}
public boolean odd(){
if(num%2==0) return false;
else return true;
}
19
Java
Thread no. 2

public static void main(String str[]){


PrimeOddThread c= new PrimeOddThread ();
c.num=2;
Thread no. 1
c.start();
if(c.odd())
System.out.println("Odd");
else System.out.println("Even"); }
}
20
Java
You can never guarantee whether
Even will be printed or Prime first.
It is totally up to the OS thread
scheduler to choose which thread
to execute first.

What will happen if you call run()


method instead of start() method ?

21
Java
Another way to create thread
class SimpleThreadR implements
Runnable{
public void run(){…}
} Calls run method of the
Runnable instance
Creation of thread – using a
passed via constructor
constructor that expects a
Thread t= Runnable object

new Thread(new SimpleThreadR() );


t.start();
22
Java
interface Runnable{
Behind the scene public void run();}

class Thread implements Runnable{…


private Runnable target;
public Thread(Runnable target){…}
public void start(){
// create OS level thread
run(); }
public void run(){
if (target != null){
target.run(); }}

Thread t=new Thread(new class SimpleThreadR


SimpleThreadR() ); implements Runnable{…
public void run(){}}
t.start();}
Let us try to implement
the PrimeOddThread
class using Runnable
interface.

Folder 3

24
Java
Can you list down all
the methods and
constructors of
Thread class we
have covered so far?

Did you notice the usage


of interface ? This is how
interface can be used as
a callback.

25
Java
Naming threads
• Using Constructors :
Thread(Runnable target, String name)
• Methods :
final void setName(String name)
final String getName()
• To find out which thread is running right
now:
Thread.currentThread().getName();
static Thread currentThread()
returns the current thread.
26
Java
Lifecycle
yield() After run()
method
start() run() completes
new ready running dead

sleep(), wait()
Waiting for IO device

Waiting /
Up to the thread scheduler to pick a Blocked
thread for execution from ready state.

27
Java
If I start two threads one after
another like the code below, then
can we guarantee that the t1 thread
will execute first and then the t2?
psvm(){
Thread t1= new
Thread(new
SimpleThreadR() );
Thread t2= new
Thread(new
SimpleThreadR() );
t1.start();
t2.start();}
28
Java
After t1 has been created there are
two active threads - main thread and
t1. Now let us say that thread
scheduler chooses t1. In that case
what you said is right- t1 executes
before t2. But now let us say main
executes, then t2 gets created. So,
now we have three threads- main, t1,
t2. If thread scheduler chooses t2 then
here is a chance that t2 executes
before t1!

29
Java
sleep()
• static void sleep(long millis) throws
InterruptedException
• static void sleep(long millis,
int nanos) throws InterruptedException
• Example:
• public class Appear implements
Runnable{
• char c[]={‘H',‘E',‘L',‘L‘,’O’};
• public void run() {

Folder 4

30
Java
int i=0;
try{
while (i<5){
System.out.print(c[i++]);
Thread.sleep(1000);
}
}catch(InterruptedException e){}
}
public static void main(String str[]){
Thread t =new Thread(new Appear());
t.start();}} 31
Java
join()

• final void join() throws


InterruptedException
• final void join(long millis) throws
InterruptedException
• final void join(long millis,
int nanos) throws InterruptedException

32
Java
class Join implements Runnable{
int num;
public void run() {
if( prime())System.out.print("Prime");
else System.out.print("Non-Prime");
}
public boolean prime(){
for(int i=2;i<num/2;i++){
if(num%i==0) return false;}
Folder 5
33
return true; Java }
public boolean odd(){
if(num%2==0)return false;
else return true; }
public static void main(String str[]){
Join s=new Join();
Thread t= new Thread(s);
s.num=55;
t.start();
boolean b=s.odd();
34
Java
main thread waits for t
try{ t.join(); to finish

}
catch(InterruptedException e){
System.out.println("main interrupted");}
if(b)
System.out.print(" and Odd");
else
System.out.print("and Even");
} }
35
Java
Are there any chances of you
letting us know why sleep() and
join() methods throw this
InterruptedException.

36
Java
Interruption
• A thread can be interrupted by calling interrupt ()
method on it.
• If this thread is blocked on account of sleep() or join()
methods, then when interrupt method is called, its
interrupt status will be cleared and it will receive an
InterruptedException.
void interrupt()
static boolean interrupted()
boolean isInterrupted()

37
Java
Why will I want a thread
to be interrupted ?

Consider a run() method that runs


continuously in a while loop. If the thread
is sleeping or waiting then it can’t
actively check whether it should continue
or terminate. This is were interrupt()
method comes in. When interrupt()
method is called on a thread object that is
currently blocked, the blocking call (such
as sleep/ join) is terminated by an
InterruptedException.
38
Java
Thread priorities
• A thread is always associated with a priority (a
number between 1 and 10, 10 being the highest).
• A thread with a higher priority will run before the
thread with lower priority.
final void setPriority(int newPriority)
final int getPriority()
• Static constants to set priorities:
Thread.MIN_PRIORITY (1)
Thread.NORM_PRIORITY (5): default
Thread.MAX_PRIORITY (10)
39
Java
Selfish threads
•In non-pre-emptive OS, a thread, which executes
with high priority and has long execution time, does
not voluntarily leave the CPU for the other threads
with similar priority, such threads are selfish thread.
•It is recommended that threads with high priority
(be unselfish) call Thread.sleep() or Thread. yield()
method.
•static void yield()
This method causes the currently executing
thread object to temporarily pause and allow other
threads to execute.

40
Java
Illegal Argument Exception
• This is a RunTimeException and it indicates that
a method has been passed an illegal or
inappropriate argument.
• The setPriority(int newPriority)method can
take values between 1 to 10. Any other int value
will result in IllegalArgumentException
exception

41
Java
Synchronization
Thread A calls withdraw(500)
Account
Thread B calls withdraw(750) money: Rs.1000
Thread A waits for the transaction to complete
Thread B waits for the transaction to complete

Thread A updates the money to (1000-500)=500 Account


Thread B updates the money to 500-750=-250 money: Rs.-250

Code…
42
Java
public class ThreadTest implements Runnable{
Account a;
int amt;
public static void main(String str[]){
Account lb= new Account(1000);
new ThreadTest(lb,"A",500);
new ThreadTest(lb,"B",750);}
public ThreadTest(Account a,String name,int
amt){
this.a=a;
Folder 7
this.amt=amt;
new Thread(this,name).start();} 43
Java
public void run(){ a.withdraw(amt);}}
class Account{
private int money;
Account(int amt){ money=amt;}
void deposit(int amt){
try{
// doing io operation
Thread.sleep(1000); }
catch(Exception e){}
money=money+amt;
System.out.println("Balance "+ money);} 44
Java
void withdraw(int amt){
if(amt<money){
try{
// doing io operation
Thread.sleep(1000); }
catch(Exception e){}
money=money-amt;
System.out.println("Received "+ amt +" by " +
Thread.currentThread().getName());
}
else 45
Java
System.out.println("Sorry "+
Thread.currentThread().getName()+ "Requested
amt ("+ amt +") is not available.");
System.out.println("Balance "+ money);
}
}
Result:
Received 500 by A
Balance 500
Received 750 by B
Balance -250
46
Java
Solution to the Account problem
Account
Thread A locks the object and calls withdraw(500) money:
Thread B waits for A to release the lock Rs.1000
Thread A waits for the transaction to complete
Thread A updates the money to (1000- Rs 500
500)=500 and releases the lock.

Thread B locks the object and calls withdraw(750) Account


money:
Thread B gets the message that it cannot withdraw Rs.500
the requested amount
Thread B releases the lock.

47
Java
Locking
• In java, the object gets locked in two situations:
• When a thread calls a synchronized method of an
object. In this case, lock is released as soon as
the method finishes its execution. No other thread
can access any synchronized methods of that
object, till the lock on the object is released.
synchronized void deposit(int amt)

48
Java
B. When an object is explicitly locked by the
statement
synchronized(object){… }
In such cases, all the methods of the object
remain locked until the block of statement
within synchronized block finishes execution.

49
Java
Synchronized Code
• Solution using approach A:
Add synchronized keyword to deposit and withdraw
methods of the Account class, compile and execute.
synchronized void deposit(int amt) synchronized
void withdraw(int amt)
•Solution using approach B:
Change the run method of ThreadTest class to
public void run(){
synchronized(a){
a.withdraw(amt); } }
Folder 8
50
Java
Result :
Received 500 by A
Balance 500
Sorry B Requested amt (750) is
not available.
Balance 500

51
Java
So what about static
methods? Can they be
synchronized?

Yes you can synchronize


static methods to protect
static data. But what happens
is that the Class object of the
corresponding object gets
locked !

52
Java
A few more points !
• synchronized methods of super class can be
overridden to be unsynchronized.
• Constructors cannot be declared as synchronized.
• A non-static inner class can lock it’s containing
class using a synchronized block.
• Methods in the interface cannot be declared as
synchronized.
• The locking does not prevent threads from
accessing unsynchronized methods.
• Synchronized methods are also called thread-safe
methods.

53
Java
Do you recall I told you StringBuffer
is thread-safe. Using StringBuffer
doesn’t allow you to take full
advantage of the multithreading. So,
if you are sure that your threads can
simultaneously call methods of same
string without causing unnecessary
side effects – use StringBuilder.

54
Java
Deadlocks

Your turn now.. Can you


explain a situation when
deadlocks can occur ?
And in lab, try to write some
java code that creates a
deadlock. Of course, this
should also be your last time to
write such code!

55
Java
Inter-thread communication
• Inter-thread communication is required when
execution of one thread depends on another thread.
In such case, the second thread intimates or
notifies the first thread when it has finished what the
first thread is waiting for.
• The best suited situation to understand this is a
producer-consumer problem.

consumer

Producer
56
Java
Methods of Object class used for
thread communication
final void wait() throws InterruptedException
final void wait(long timeout) throws
InterruptedException
The above methods causes current thread to wait until either
another thread invokes the notify() method or the notifyAll()
method for this object, or a specified amount of time has
elapsed.

final void notify(): Wakes up a single thread that is


waiting on this object's lock.
final void notifyAll(): Wakes up all threads that are
waiting on this object's lock.

57
Java
wait() and notify()
• Both of these methods must be called from a
synchronized context. If this is not done
IllegalMonitorStateException is thrown at
runtime.
• When a thread calls wait() method, it relinquishes
the lock on the object (unlike sleep method).
• When a thread calls notify() method, the lock is not
released.
• Another word frequently used for lock is monitor.

58
Java
public class ProducerConsumer implements
Runnable{
int apples;
public static void main(String s[]){
ProducerConsumer pc = new ProducerConsumer();
Thread producer= new Thread(pc, "Tree");
Thread consumer1= new Thread(pc, "Earthworm");
Thread consumer2= new Thread(pc, "Man");
producer.start();
consumer1.start();
consumer2.start();}
59
Java
synchronized void produce(){
while(true){
if(apples>100) Produce apples only if there
are <=100 apples
try{
System.out.println("Waiting for apples to be
eaten");
wait(); }catch(InterruptedException e){}
try{
int i=(int)(Math.random()*500); Produce apples
Thread.sleep(i);
apples=apples+i; Simulating time taken to
produce apples. 60
Java
System.out.println("Produced apples ="+ apples);
}catch(InterruptedException e){}
notifyAll(); } }
Wake all the consumers

synchronized void consume(){


while(true){
int i=(int)(Math.random()*1000);
Note that consumer will eat less
if(apples<(i/10)) than 100 at one time.
try{
System.out.println(Thread.currentThread().getName
() +" waiting for more apples");
wait(); }catch(InterruptedException e){} 61
Java
try{
System.out.println(Thread.currentThread().getName
()+ " busy eating "+ i/10 +" apples");
Simulating time taken to eat
Thread.sleep(i); apples.
apples=apples-i/10; }
catch(InterruptedException e){}
notify(); } }
public void run(){
if(Thread.currentThread().getName().equals("Tree"
))
produce();
else consume(); }} 62
Java
Produced apples =111
Waiting for apples to be eaten
Earthworm busy eating 86 apples
Earthworm waiting for more apples
Man busy eating 8 apples
Sample result
Man busy eating 5 apples
Man waiting for more apples
Produced apples =124
Waiting for apples to be eaten
Earthworm busy eating 85 apples
Earthworm busy eating 20 apples 63
Java
Daemon threads
• A program continues to execute as long as it has
at least one (non-daemon) thread that is alive.
• The threads we have seen so far are non-
daemon.
• Daemon threads are the threads which cease to
execute when there are no non-daemon threads
alive.
• Example: garbage collector thread.
• final void setDaemon(boolean on)
• boolean isDaemon()

64
Java
Challenge your mind

Go through the code given


in the next slide carefully.
Try and answer the
question listed below the
code. You can take 24
hours to think !

65
Java
class A extends Thread {
String sa;
public A(String sa) {this.sa = sa;}
public void run() {
synchronized (sa) {
while(!sa.equals("Done")){
try{sa.wait();}
catch(Exception e){}
}
}
System.out.println(sa);
}
}
66
Java
class B {
private static String sa = new
String("Not Done");
public static void main (String[]
args) {
synchronized (sa) {
Thread t1 = new A(sa);
t1.start();
sa="Done";
sa.notify();
}
}}
On executing the above code, it throws
IllegalMonitorStateException . Why?
67
Java
Thread Groups
• Thread groups are collection of threads into one object .
• This helps in manipulating a collection of threads all at a
time instead of manipulating each of them individually .
• For instance all the threads in a collection can be started
together.
• Every Java thread is a member of some thread group.
When a thread is created, unless it is explicitly put in a
thread group, the runtime system automatically places
the new thread in the same group as the thread that
created it.
• When a Java application first starts up, the Java runtime
system creates a ThreadGroup named "main".

68
Java
Creating the ThreadGroup
• ThreadGroup(String name)
• ThreadGroup(ThreadGroup parent,
String name)

• final ThreadGroup getThreadGroup()


Is a method of Thread class that returns the
thread group the calling thread belongs to.

69
Java
Methods of a ThreadGroup
• Methods to enumerate:
– int enumerate(Thread[] list)
– int enumerate(Thread[] list,
boolean recurse)
• Methods with respect to the group
– int activeCount()
– ThreadGroup getParent()
– String getName()
– boolean parentOf(ThreadGroup g)
70
Java
class EnumeratedThreads {
public static void main(String s[]) {
ThreadGroup currentGroup =
Thread.currentThread().getThreadGroup();
int no;
Thread listOfThreads[];
no = currentGroup.activeCount();
listOfThreads = new Thread[no];

currentGroup.enumerate(listOfThreads);
for (int i = 0; i < no; i++) {
System.out.println("Thread #" +
i + " = " + listOfThreads[i].getName());
}
}} 71
Java
Methods to with respect to the
threads as a group
• int getMaxPriority()
• void setMaxPriority(int pri)
• void interrupt()
• void destroy()
• boolean isDaemon()
• void setDaemon(boolean daemon )
• void list()

72
Java
class ThreadGroupDemo{
public static void main (String [] args){
ThreadGroup tg = new ThreadGroup ("group
1");
Thread t1 = new Thread (tg, "thread 1");
Thread t2 = new Thread (tg, "thread 2");
Thread t3 = new Thread (tg, "thread 3");

tg = new ThreadGroup ("group 2");


Thread t4 = new Thread (tg, "thread 4");

tg = Thread.currentThread
().getThreadGroup ();
73
Java
int agc = tg.activeGroupCount ();
System.out.println ("Active thread
groups in " + tg.getName () +" thread
group: " + agc);
tg.list ();
}
}

Active thread groups in main thread group: 2


java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
java.lang.ThreadGroup[name=group 1,maxpri=10]
java.lang.ThreadGroup[name=group 2,maxpri=10]
74
Java

S-ar putea să vă placă și