You are on page 1of 38

Java Threads

Instructor:
I t t Mainak
M i k Ch
Chaudhuri
dh i
mainakc@cse iitk ac in
mainakc@cse.iitk.ac.in

1
Java threads
• Two ways to create a thread
– Extend the Thread class and override the public run
method
– Implement
I l a runnable
bl interface
i f with
i h a public
bli run
method
class MyThread
y extends Thread {
private int tid;
private String name;
private
i llong startTime;
Ti
public MyThread (String name, int tid) {
super (name);
this.tid = tid;
this.name
th s.name = new String(name);
Str ng(name);
startTime = System.currentTimeMillis(); 2
} // next slide
Java threads
public
bli void
id run () { // override
id
System.out.println (“<” + age() + “> Hi! This is ”
+ getName() + “.”);
. );
}
public long age () {
p
return (System.currentTimeMillis () –
startTime);
}
} // end class

class MyFirstThreadDemo {
public static void main (String arg[]) {
Integer n = new Integer (arg[0].trim());
int numThreads = n.intValue(); // next slide
3
Java threads
int i;
MyThread
y t[]
[] = new
MyThread[numThreads];
for (i=0; i<numThreads; i++) {
t[i] = new MyThread (“Thread ”+i, i);
t[i] t t()
t[i].start();
}
} // end main
} // end class
4
Java threads via interface
class MyThread implements Runnable {
private int tid;
private String name;
private long startTime;
public MyThread (String name,
name int tid) {
this.tid = tid;
this.name = new String(name);
startTime = System.currentTimeMillis();
}
public void run () {
System.out.println (“<” + age() + “> Hi! This is ”
+ Thread.currentThread().getName()
Thread currentThread() getName() + “.”); );
} //next slide 5
Java threads via interface
public long age () {
return (System.currentTimeMillis () –
startTime);
}
} // end class

class MyFirstThreadDemo {
publi st
public static
ti void
id m
main
in (String
(St in arg[])
[]) {
Integer n = new Integer (arg[0].trim());
int numThreads
h d = n.intValue();
l ()
6
int i; // next slide
Java threads via interface
MyThread mt[] = new
y [
MyThread[numThreads]; ]
Thread t[] = new Thread[numThreads];
for (i=0;
(i 0; i<numThreads;
i numThreads; ii++)) {
mt[i] = new MyThread (“Thread ”+i,
i);
t[i] = new Thread (mt[i], “Thread ”+i);
t[i] start();
t[i].start();
}
} // endnd main
m in
} // end class 7
Announcements
• Final exam on 19th November 1215 to
1515
• Seating arrangement:
Y4 Y5
Y4, Y5, Y7001 to Y7085 L1 OROS
Y7092 to Y7233 L2 ERES
Y7234 tot Y7388 L16 OROS
Y7391 to Y7518 L17 ERES
• Please take seats 15 minutes before the
scheduled time
8
Java thread states
• Java threads have typically
ll seven states
– New: just after a thread is created
– Runnable: after the start() method is
invoked. The thread is placed in the runnable
set or the ready queue
queue. When scheduled,
scheduled the
run() method will be executed.
g executing
– Running: g the code in the run()
()
method. May call its yield() method to put
itself back in the runnable set.
– Suspended:
S d d after
ft ththe suspend()
d() method
th d iis
called. May be called by itself or by some
other thread. It is placed back on runnable
set only if some other thread calls its
resume() method.
9
Java thread states
• Seven states (continued)
– Blocked: after the sleep() method or the
wait() method or the join() method is called
to join with a thread (at a barrier) that is
yet to arrive at the join point or when it
d
does bl
blocking
ki I/O (e.g.,
( reading
di f from
keyboard). The thread transitions back to
runnable state when the blocking call is over.
– Suspended-blocked: If a blocked thread is
suspended by some other thread. It returns
b k to suspended
back d d or bl
blocked
k d state
depending on whether the blocking finishes
before a call to resume() or not.
not
– Dead: On completion of the run() method10 or
a call to stop() method.
Java thread scheduling
• Every Java thread gets a priority
– Inherits the same priority from the creating
thread In our example
thread. example, all threads have
same priority as the “main thread”.
g from MIN_PRIORITY to
– Priorities range
MAX_PRIORITY defined in Thread class.
The default priority is NORM_PRIORITY.
– Use
Us setPriority
s tP i it and nd getPriority
tP i it m methods
th ds to
t
change and query a thread’s priority.
– Among all the threads in the runnable set,
set
the highest priority thread is allowed to run
until it blocks, yields, gets suspended, or a
new thread
th d of
f hi
higher
h priority
i it enters
t th
the
runnable set. In the last case the running11
thread goes back to runnable set
Java thread scheduling
• Some implementations carry out a round-
robin scheduling (e.g., JDK 1.1 for
Windows 95/NT)
– Everyy thread gets
g a time slice to execute
– Once the time slice of the thread expires, it
is put back in the runnable set and the next
thread is given a chance (higher priority
threads are considered first)
– If a thread
h d blocks,
bl k yields,
i ld or gets suspended
d d
before the time slice expires, the next
thread is scheduled for execution
12
More example
class MyThread extends Thread {
private int tid;
p i t St
private String
in n name;
m ;
private long startTime;
private long screamingInterval;
public MyThread (String name, int tid, long
screamingInterval) {
super ((name);)
this.tid = tid;
this name = new String(name);
this.name
startTime = System.currentTimeMillis();
this.screamingInterval = screamingInterval;
} // next slide 13
More example
public void run () { // override
long count = 0;
while (true) {
if (count % screamingInterval == 0) {
System.out.println
y p (“<”
( + age()
g () + “> Hi! This is ” +
getName() + “.”);
}
count++;
}
}
public long age () {
return (System.currentTimeMillis () – startTime);
}
} // end class 14
More example
class MyThreadDemo {
public static void main (String arg[]) {
Int
Integer n = new
n Integer
Int ((arg[0].trim());
[0] t im());
int numThreads = n.intValue();
int i;
MyThread t[] = new MyThread[numThreads];
for ((i=0; i<numThreads; i++)) {
t[i] = new MyThread (“Thread ”+i, i,
(i+1)*1000000);
//t[i] setPriority (t[i]
//t[i].setPriority (t[i].getPriority()+i);
getPriority()+i);
t[i].start();
}
} // end main 15
} // end class
Typical output snapshot
<8408> Hi! This is Thread 0.
<9014> Hi! This is Thread 0.
<9374>
9374> Hi! This is Th
Thread
d 11.
<9615> Hi! This is Thread 0.
<10214> Hi! This is Thread 0.0
<10545> Hi! This is Thread 1.
<10813> Hi! This is Thread 0.
<11416> Hi! This is Thread 0.
<11720> Hi! This is Thread 1.
<12014>
12014 Hi! This
Thi isi Thread
Th d0 0.
<12613> Hi! This is Thread 0.
<12889> Hi! This is Thread 1.1
<13213> Hi! This is Thread 0. 16
Physical resources
• Parallelism ultimately depends on
availability of multiple physical CPUs
– You get true concurrency with
“multiprocessors”
– With single
i l CPU
CPU, you gett time-shared
ti h d
concurrency (at any point in time only one
thread can run)
– Today small-scale multiprocessors are
commodity
– Chip-multiprocessors or so called multi-core
processors come with two, four, or eight
processors on a single chip (soon 16
processors) 17
Data race
• How to share a variable?
– Create
r a a single
ng class
a containing
n a n ng the variables
ar a
that you want to share
j
– Create one instance of this object and
attach multiple threads to it
pp
– Let us see what happens if we try
y to update
p
a shared variable concurrently in multiple
threads
– This is known as a data race as multiple
threads may have a race trying to update the
same data
18
Data race
class MyThread implements Runnable {
private long sum;
p bli MyThread
public M Th d () {
sum=0;
}
public void run () {
int i;
for (i=0; i<100000; i++) {
sum++;
}
System.out.println("<" +
Thread.currentThread().getName() + ">:: Sum="
Sum
+ sum);
19
} // next slide
Data race
public long GetSum () {
return sum;
}
} // end class

class MyDataRaceDemo {
public static void main (String arg[])
throws java.lang.InterruptedException
java lang InterruptedException {
Integer n = new Integer (arg[0].trim());
i t numThreads
int Th d = n.intValue();
i tV l ()
int i; // next slide 20
Data race
MyThread mt = new MyThread();
Thread t[] = new Thread[numThreads];
f (i
for (i=0;
0; ii<numThreads;
n mTh ds; i++)
i ){
t[i] = new Thread (mt, "Thread "+i);
t[i] start();
t[i].start();
}
for ((i=0; i<numThreads; i++)) {
t[i].join();
}
S t
System.out.println("From
t i tl ("F main:
i SSum="" +
mt.GetSum());
} // end main
} // end class 21
Data race
• If you run this program multiple times,
you will get
y g different outputs
p in
different runs
– A typical
yp symptom
ymp m of f data race
– The output depends on how the threads get
interleaved when theyy run
– A typical output:
hr a 0>: Sum=107927
<Thread um 79 7
<Thread 1>: Sum=128853
From main: Sum
Sum=128853
128853
22
More data race example
• Let us try to write the program for summing an array
class MyThread implements Runnable {
private int array[];
private long sum;
private int numThreads;
private int tid;
public MyThread (long size, int numThreads) {
int i;
array = new int[size];
for (i=0; i<size; i++) {
array[i] = i;
}
sum = 0;
tid = 0;
this.numThreads = numThreads; 23
} // next slide
More data race example
public void run () {
int i;
int myid = tid++; // data race on tid
for (i=myid*(array.length/numThreads);
i (m id 1)*(
i<(myid+1)*(array.length/numThreads);
l n th/n mTh ds); ii++)) {
sum += array[i]; // data race on sum
}
}
public long GetSum() {
return sum;
}
} // end class 24
More data race example
class MyArraySumDemo {
public static void main (String
p ( g arg[])
g[]) throws
java.lang.InterruptedException {
Integer n = new Integer (arg[0].trim());
long size = n.intValue();
g (arg[1].trim());
n = new Integer ( g[ ] ())
int numThreads = n.intValue();
int i;;
MyThread mt = new MyThread(size,
numThreads); )
Thread t[] = new Thread[numThreads]; 25
// next slide
More data race example
for (i=0; i<numThreads; i++) {
[ ] = new Thread ((mt, "Thread "+i);
t[i] )
t[i].start();
}
for (i=0; i<numThreads; i++) {
t[i].join();
}
System out println("From
System.out.println( From main: Sum=
Sum=" +
mt.GetSum() + “[Expected=” + (size*(size-1))/2
+ “]”);
])
} // end main 26

} // end class
More data race example
• One typical output for size=100000 and
numThreads=2
From main: Sum=3692782245[Expected=4999950000]
• Replacing
Replac ng sum by local sum and
accumulating at the end reduces the
chance of data race
– Reduces the number of executed critical
sections: more parallelism
p
– But the program is still buggy and may
produce wrong
p g results once in a while
27
More data race example
class MyThread implements Runnable {
private int array[];
p i t llong
private n ssum; m;
private int numThreads;
private int tid;
public MyThread (long size, int numThreads) {
int i;
array = new int[size];
for (i=0; i<size; i++) {
array[i]
[i] = ii;
}
sum = 0;
this.numThreads = numThreads; 28

} // next slide
More data race example
public void run () {
int i;
l n localSum
long l lS m = 0; // pprivate
i t variable
i bl
int myid = tid++; // data race on tid
for (i=myid*(array
(i=myid (array.length/numThreads);
length/numThreads);
i<(myid+1)*(array.length/numThreads); i++) {
localSum += array[i]; // no data race
}
sum += localSum; // data race on sum
}
public long GetSum() {
return sum;
} 29
} // end class
More data race example
class MyArraySumDemo {
public static void main (String
p ( g arg[])
g[]) throws
java.lang.InterruptedException {
Integer n = new Integer (arg[0].trim());
long size = n.intValue();
g (arg[1].trim());
n = new Integer ( g[ ] ())
int numThreads = n.intValue();
int i;;
MyThread mt = new MyThread(size,
numThreads); )
Thread t[] = new Thread[numThreads]; 30
// next slide
More data race example
for (i=0; i<numThreads; i++) {
[ ] = new Thread ((mt, "Thread "+i);
t[i] )
t[i].start();
}
for (i=0; i<numThreads; i++) {
t[i].join();
}
System out println("From
System.out.println( From main: Sum=
Sum=" +
mt.GetSum() + “[Expected=” + (size*(size-1))/2
+ “]”);
])
} // end main 31

} // end class
Fixing data races
• Every Java object has an in-built lock
– We
W will
w makema use
u of f this to protect
pr the
critical sections
– For every y shared variable that is involved in
a data race, we need to create a lock
– It is p
possible to have a single
g lock to resolve
multiple races, but that will limit concurrency
(why?)
– General solution: create a dummy object and
use its lock to resolve a race
– Java
J allows
ll the
h programmer to mark k critical
i i l
sections with the keyword synchronized32
Fixing array sum
class MyThread implements Runnable {
private int array[];
p i t llong
private n ssum;
m;
private int numThreads;
private int tid;
private Object tidLock; // dummy object
private Object
p j sumLock; // dummyy object
j
public MyThread (long size, int numThreads,
Object tidLock, Object sumLock) {
int i;
array = new int[size];
for (i=0;
(i 0; i<size;
i size; i++)
i ){
array[i] = i; 33
} // next slide
Fixing array sum
sum = 0;
this.numThreads = numThreads;
this.tidLock = tidLock;
this sumLock = sumLock;
this.sumLock
}
public void run () {
int i;
i t myid;
int id
synchronized (tidLock) {
myid = tid++;
34
} // next slide
Fixing array sum
for (i=myid*(array.length/numThreads);
i<(myid+1)*(array.length/numThreads); i++) {
synchronized
h i d ((sumLock)
L k) {
sum += array[i];
}
}
}

public long GetSum() {


return sum;
}
} // end class 35
Fixing array sum
class MyArraySumDemo {
public static void main (String arg[]) throws
java lang InterruptedException {
java.lang.InterruptedException
Integer n = new Integer (arg[0].trim());
long
g size = n.intValue();
();
n = new Integer (arg[1].trim());
int numThreads = n.intValue();
int i;
Object tidLock = new Object();
Object sumLock = new Object();
MyThread mt = new MyThread(size,
numThreads,, tidLock,, sumLock);)
Thread t[] = new Thread[numThreads];
36
// next slide
Fixing array sum
for (i=0; i<numThreads; i++) {
[ ] = new Thread ((mt, "Thread "+i);
t[i] )
t[i].start();
}
for (i=0; i<numThreads; i++) {
t[i].join();
}
System out println("From
System.out.println( From main: Sum=
Sum=" +
mt.GetSum() + "[Expected=" + (size*(size-1))/2
+ "]");
] )
} // end main 37

} // end class
Announcements
• No class tomorrow
• All the best for the final exam
exam. Bye!

38

You might also like