CS244 Lec5-Threads
CS244 Lec5-Threads
Dr Walid M. Aly
Threads
1
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Introduction
6
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Example on thread blocking
The thread executing the code will be blocked at line 2 until there are data to read.
java.io.DataInputStream
public final int readInt()
Reads four input bytes and returns an int Value
This method blocks until input data is available
7
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Example 1 : Dealing with the main Thread
class CurrentThreadDemo {
public static void main(String args[]) {
Thread t = Thread.currentThread();
System.out.println("Current thread: " + t);
t.setName("My Thread");
System.out.println("After name change: " + t);
try {
for(int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
…..
}}
java.lang.Thread
public static Thread currentThread()
Returns a reference to the currently executing thread object
public String toString() Returns a string representation of this thread, including the
thread's name, priority, and thread group.
public static void sleep(long millis) throws InterruptedException Causes the currently 10
executing thread
CC316-CS244-Lec#9-Dr toAlysleep (temporarily cease execution) for the specified milliseconds.
Walid M.
How to create Threads?
class ThreadDemo {
class ThreadDemo {
public static void main(String args[]) {
public static void main(String args[]) {
A a=new A();
A a=new A( );
Thread t = new Thread(a);
a.start(); // Start the thread and execute run
t.start(); /// Start the thread and execute run
}
}
}
}
Calling start () automatically invokes run() :if you can call run() directly, instead of calling start()
12
no new thread is created
CC316-CS244-Lec#9-Dr Walid M. Aly and program executed within the same thread
Creating threads by extending Thread
public class Client extends Thread {
String name;
public Client(String name){
this.name=name;}
public void run(){
System.out.println("Serving client.... :"+ name);
try{
Thread.sleep(1000);}
catch (Exception ex){}
System.out.println("End Serving client :"+ name);
} Nondeterministic
}}} output
class ClientServer {
public static void main(String args[]) {
Client client1=new Client("Ahmed ");
Client client2=new Client("Mohamed ");
Client client3=new Client("Tarek");
client1.start(); // Start the thread
client2.start(); // Start the thread
client3.start(); // Start the thread
13
}}
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Creating a thread by implementing Runnable
public class Client implements Runnable {
String name;
public Client(String name){
this.name=name;}
public void run(){
System.out.println("Serving client.... :"+ name);
try{Thread.sleep(1000);}
catch (Exception ex){} Nondeterministic
System.out.println("End Serving client :"+ name); output
}}
class ThreadDemo {
public static void main(String args[]) {
Client client1=new Client("Ahmed ");
Client client2=new Client("Mohamed ");
Client client3=new Client("Taerk");
Thread t1=new Thread(client1);
Thread t2=new Thread(client2);
Thread t3=new Thread(client3);
t1.start(); // Start the thread
t2.start(); // Start the thread
t3.start(); // Start the thread
}} 14
CC316-CS244-Lec#9-Dr Walid M. Aly
17:10
Thread Synchronization
• A shared resource may be corrupted if it is accessed
simultaneously by multiple threads.
• A class is said to be thread safe if an object of the class does
not cause a race condition in the presence of multiple threads.
17
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Unsafe Flight Booking public class Client implements Runnable {
private Flight f;
public class Flight {
private int seats;
private int availableSeats=100;
private String name;
public boolean bookFlight(int
public Client(Flight f, int seats, String name){
seats,String customer)
this.f=f;
{
this.seats=seats;
System.out.println("Booking for
this.name=name;
customer: " + customer);
}
if (availableSeats>=seats)
public void run(){
{
f.bookFlight(seats,name);
System.out.println("Booking successful for
}}
customer: " + customer);
try{ public class EgyptAir{
Thread.sleep(1000);} public static void main(String args[]){
catch (Exception ex){} Flight f=new Flight();
availableSeats-=seats; Client c1=new Client(f,10,"Ahmed");
return true; Client c2=new Client(f,90,"Mohamed");
} Client c3=new Client(f,5,"Aly");
else{ Thread t1 = new Thread(c1);
System.out.println("Booking failed for Thread t2 = new Thread(c2);
Customer: " + customer); Thread t3 = new Thread(c3);
return false; t1.start();t2.start();t3.start();
}}} }} 18
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Synchronization
Thread B waits for Thread A
a monitor is a very small box that can hold only one thread. Once a thread enters a
monitor, all other threads must wait until that thread exits the monitor. In this way, a
monitor can be used to protect a shared asset from being manipulated by more than one
thread at a time.
You create a monitor by adding th identifier word synchronized to the method signature
public synchronized void m(){}
Once a thread is inside a synchronized method, it acquires the lock for the object that
called the synchronized code, no other thread can call any other synchronized method on
the same object until the thread exit the synchronized method and releases the lock.
19
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
safe Flight Booking
20
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Interthread Communication
Java includes an elegant interprocess communication mechanism via the wait( ), notify( ), and
notifyAll( ) methods.
All three methods are defined in class Object can be called only from within a synchronized
context.
■ wait( ) tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify( ) or notifyAll.
■ notify( ) wakes up a thread that called wait( ) on the same object.
■ notifyAll( ) wakes up all the threads that called wait( ) on the same object.
Release lock
21
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
An incorrect implementation of a producer and consumer
class Consumer implements Runnable {
class Q { Put: 1
Q q;
int n; Got: 1
Consumer(Q q) {
synchronized int get() { Got: 1
this.q = q;
System.out.println("Got: " + n); Got: 1
new Thread(this, "Consumer").start();
return n; } Got: 1
} public void run() { Got: 1
synchronized void put(int n) { while(true) { Put: 2
this.n = n; q.get(); Put: 3
System.out.println("Put: " + n); } Put: 4
}} }
Put: 5
}
Put: 6
class Producer implements Runnable {
Put: 7
Q q;
Got: 7
Producer(Q q) {
class PC {
this.q = q;
public static void main(String args[]) {
new Thread(this,"Producer").start(); Q q = new Q();
} new Producer(q);
public void run() { new Consumer(q);
int i = 0; }
while(true) { }
q.put(i++);
}}} 23
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
A correct implementation of a producer and consumer.
Thread1 Thread2
25
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10
Deadlock Demo
class Deadlock implements Runnable {
class A { A a = new A();
synchronized void foo(B b) { B b = new B();
String name = Thread.currentThread().getName(); Deadlock() {
System.out.println(name + " entered A.foo"); Thread.currentThread().setName("MainThread");
try { Thread t = new Thread(this, "RacingThread");
Thread.sleep(1000); t.start();
} catch(Exception e) { a.foo(b); // get lock on a in this thread.
System.out.println("A Interrupted"); System.out.println("Back in main thread");
} }
System.out.println(name + " trying to call B.last()"); public void run() {
b.last(); b.bar(a); // get lock on b in other thread.
} System.out.println("Back in other thread");
synchronized void last() { }
System.out.println("Inside A.last"); public static void main(String args[]) {
}} new Deadlock();
class B { }}
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
System.out.println(name + " trying to call A.last()");
a.last();}
synchronized void last() {
System.out.println("Inside A.last");}}
Deadlock.java
27
CC316-CS244-Lec#9-Dr Walid M. Aly 17:10