Introduction To Programming 2
Introduction To Programming 2
Introduction To Programming 2
Introduction to Programming 2 1
Topics
Thread Definition
Thread Basics
− Thread States
− Priorities
The Thread Class
− Constructor
− Constants
− Methods
Introduction to Programming 2 2
Topics
Creating Threads
− Extending the Thread Class
− Implementing the Runnable Interface
− Extending vs. Implementing
Synchronization
− Locking an Object
Interthread Communication
Concurrency Utilities
Introduction to Programming 2 3
Threads
Why threads?
− Need to handle concurrent processes
Definition
− Single sequential flow of control within a program
− For simplicity, think of threads as processes executed by a program
− Example:
Operating System
HotJava web browser
Introduction to Programming 2 4
Threads
Introduction to Programming 2 5
Thread States
A thread can in one of several possible states:
1. Running
Currently running
In control of CPU
2. Ready to run
Can run but not yet given the chance
3. Resumed
Ready to run after being suspended or block
4. Suspended
Voluntarily allowed other threads to run
5. Blocked
Waiting for some resource or event to occur
Introduction to Programming 2 6
Thread Priorities
Why priorities?
− Determine which thread receives CPU control and gets to be
executed first
Definition:
− Integer value ranging from 1 to 10
− Higher the thread priority → larger chance of being executed first
− Example:
Two threads are ready to run
First thread: priority of 5, already running
Second thread = priority of 10, comes in while first thread is running
Introduction to Programming 2 7
Thread Priorities
Context switch
− Occurs when a thread snatches the control of CPU from another
− When does it occur?
Running thread voluntarily relinquishes CPU control
Running thread is preempted by a higher priority thread
More than one highest priority thread that is ready to run
− Deciding which receives CPU control depends on the operating
system
− Windows 95/98/NT: Uses time-sliced round-robin
− Solaris: Executing thread should voluntarily relinquish CPU control
Introduction to Programming 2 8
The Thread Class: Constructor
Has eight constructors
Introduction to Programming 2 9
The Thread Class: Constants
Contains fields for priority values
Introduction to Programming 2 10
The Thread Class: Methods
Some Thread methods
Introduction to Programming 2 11
A Thread Example
1 import javax.swing.*;
2 import java.awt.*;
3 class CountDownGUI extends JFrame {
4 JLabel label;
5 CountDownGUI(String title) {
6 super(title);
7 label = new JLabel("Start count!");
8 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
9 getContentPane().add(new Panel(),orderLayout.WEST);
10 getContentPane().add(label);
11 setSize(300,300);
12 setVisible(true);
13 }
14 //continued...
Introduction to Programming 2 12
A Thread Example
1 void startCount() {
2 try {
3 for (int i = 10; i > 0; i--) {
4 Thread.sleep(1000);
5 label.setText(i + "");
6 }
7 Thread.sleep(1000);
8 label.setText("Count down complete.");
9 Thread.sleep(1000);
10 } catch (InterruptedException ie) {
11 }
12 label.setText(Thread.currentThread().toString());
13 }
14 //continued...
Introduction to Programming 2 13
A Thread Example
1 public static void main(String args[]) {
2 CountDownGUI cdg =
3 new CountDownGUI("Count down GUI");
4 cdg.startCount();
5 }
6 }
Introduction to Programming 2 14
Creating Threads
Two ways of creating threads:
− Extending the Thread class
− Implementing the Runnable interface
Introduction to Programming 2 15
Extending the Thread Class
1 class PrintNameThread extends Thread {
2 PrintNameThread(String name) {
3 super(name);
4 start(); //runs the thread once instantiated
5 }
6 public void run() {
7 String name = getName();
8 for (int i = 0; i < 100; i++) {
9 System.out.print(name);
10 }
11 }
12 }
13 //continued
Introduction to Programming 2 16
Extending the Thread Class
1 class TestThread {
2 public static void main(String args[]) {
3 PrintNameThread pnt1 =
4 new PrintNameThread("A");
5 PrintNameThread pnt2 =
6 new PrintNameThread("B");
7 PrintNameThread pnt3 =
8 new PrintNameThread("C");
9 PrintNameThread pnt4 =
10 new PrintNameThread("D");
11 }
12 }
Introduction to Programming 2 17
Extending the Thread Class
Can modify main method as follows:
1.class TestThread {
2. public static void main(String args[]) {
3. new PrintNameThread("A");
4. new PrintNameThread("B");
5. new PrintNameThread("C");
6. new PrintNameThread("D");
7. }
8.}
Introduction to Programming 2 18
Extending the Thread Class
Sample output:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDA
BCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDAB
CDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
ABCDABCDABCDABCDABCDABCDABCDABCDABCDBCDBCDBCDBCDBCDBC
DBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDB
CDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCD
BCDBCDBCDBCDBCDBCDBCDBCDBCD
Introduction to Programming 2 19
Implementing
the Runnable Interface
Only need to implement the run method
− Think of run as the main method of created threads
Example:
1 class TestThread {
2 public static void main(String args[]) {
3 new PrintNameThread("A");
4 new PrintNameThread("B");
5 new PrintNameThread("C");
6 new PrintNameThread("D");
7 }
8 }
9 //continued...
Introduction to Programming 2 20
Implementing
the Runnable Interface
1.class PrintNameThread implements Runnable {
2. Thread thread;
3. PrintNameThread(String name) {
4. thread = new Thread(this, name);
5. thread.start();
6. }
7. public void run() {
8. String name = thread.getName();
9. for (int i = 0; i < 100; i++) {
10. System.out.print(name);
11. }
12. }
13.}
Introduction to Programming 2 21
Extending vs. Implementing
Choosing between these two is a matter of taste
Implementing the Runnable interface
− May take more work since we still
Declare a Thread object
Call the Thread methods on this object
− Your class can still extend other class
Extending the Thread class
− Easier to implement
− Your class can no longer extend any other class
Introduction to Programming 2 22
Example: The join Method
Causes the currently running thread to wait until the thread
that calls this method finishes execution
Example:
1 class PrintNameThread implements Runnable {
2 Thread thread;
3 PrintNameThread(String name) {
4 thread = new Thread(this, name);
5 thread.start();
6 }
7 //continued
Introduction to Programming 2 23
Example: The join Method
1 public void run() {
2 String name = thread.getName();
3 for (int i = 0; i < 100; i++) {
4 System.out.print(name);
5 }
6 }
7 }
8 class TestThread {
9 public static void main(String args[]) {
10 PrintNameThread pnt1 = new PrintNameThread("A");
11 PrintNameThread pnt2 = new PrintNameThread("B");
12 PrintNameThread pnt3 = new PrintNameThread("C");
13 PrintNameThread pnt4 = new PrintNameThread("D");
14 //continued...
Introduction to Programming 2 24
Example: The join Method
1 System.out.println("Running threads...");
2 try {
3 pnt1.thread.join();
4 pnt2.thread.join();
5 pnt3.thread.join();
6 pnt4.thread.join();
7 } catch (InterruptedException ie) {
8 }
9 System.out.println("Threads killed.");
10 }
11 }
12 //try removing the entire catch block
Introduction to Programming 2 25
Synchronization
Why synchronize threads?
− Concurrently running threads may require outside resources or
methods
− Need to communicate with other concurrently running threads to
know their status and activities
− Example: Producer-Consumer problem
Introduction to Programming 2 26
An Unsynchronized Example
1 class TwoStrings {
2 static void print(String str1, String str2) {
3 System.out.print(str1);
4 try {
5 Thread.sleep(500);
6 } catch (InterruptedException ie) {
7 }
8 System.out.println(str2);
9 }
10 }
11 //continued...
Introduction to Programming 2 27
An Unsynchronized Example
1 class PrintStringsThread implements Runnable {
2 Thread thread;
3 String str1, str2;
4 PrintStringsThread(String str1, String str2) {
5 this.str1 = str1;
6 this.str2 = str2;
7 thread = new Thread(this);
8 thread.start();
9 }
10 public void run() {
11 TwoStrings.print(str1, str2);
12 }
13 }
14 //continued...
Introduction to Programming 2 28
An Unsynchronized Example
1 class TestThread {
2 public static void main(String args[]) {
3 new PrintStringsThread("Hello ", "there.");
4 new PrintStringsThread("How are ", "you?");
5 new PrintStringsThread("Thank you ",
6 "very much!");
7 }
8 }
Introduction to Programming 2 29
An Unsynchronized Example
Sample output:
Hello How are Thank you there.
you?
very much!
Introduction to Programming 2 30
Synchronization:
Locking an Object
Locking of an object:
− Assures that only one thread gets to access a particular method
− Java allows you to lock objects with the use of monitors
Object enters the implicit monitor when the object's synchronized method is
invoked
Once an object is in the monitor, the monitor makes sure that no other thread
accesses the same object
Introduction to Programming 2 31
Synchronization:
Locking an Object
Synchronizing a method:
− Use the synchronized keyword
Prefixed to the header of the method definition
Can synchronize the object of which the method is a member of
synchronized (<object>) {
//statements to be synchronized
}
Introduction to Programming 2 32
First Synchronized Example
1 class TwoStrings {
2 synchronized static void print(String str1,
3 String str2) {
4 System.out.print(str1);
5 try {
6 Thread.sleep(500);
7 } catch (InterruptedException ie) {
8 }
9 System.out.println(str2);
10 }
11 }
12 //continued...
Introduction to Programming 2 33
First Synchronized Example
1 class PrintStringsThread implements Runnable {
2 Thread thread;
3 String str1, str2;
4 PrintStringsThread(String str1, String str2) {
5 this.str1 = str1;
6 this.str2 = str2;
7 thread = new Thread(this);
8 thread.start();
9 }
10 public void run() {
11 TwoStrings.print(str1, str2);
12 }
13 }
14 //continued...
Introduction to Programming 2 34
First Synchronized Example
1 class TestThread {
2 public static void main(String args[]) {
3 new PrintStringsThread("Hello ", "there.");
4 new PrintStringsThread("How are ", "you?");
5 new PrintStringsThread("Thank you ",
6 "very much!");
7 }
8 }
Introduction to Programming 2 35
First Synchronized Example
Sample output:
Hello there.
How are you?
Thank you very much!
Introduction to Programming 2 36
Second Synchronized Example
1 class TwoStrings {
2 static void print(String str1, String str2) {
3 System.out.print(str1);
4 try {
5 Thread.sleep(500);
6 } catch (InterruptedException ie) {
7 }
8 System.out.println(str2);
9 }
10 }
11 //continued...
Introduction to Programming 2 37
Second Synchronized Example
1 class PrintStringsThread implements Runnable {
2 Thread thread;
3 String str1, str2;
4 TwoStrings ts;
5 PrintStringsThread(String str1, String str2,
6 TwoStrings ts) {
7 this.str1 = str1;
8 this.str2 = str2;
9 this.ts = ts;
10 thread = new Thread(this);
11 thread.start();
12 }
13 //continued...
Introduction to Programming 2 38
Second Synchronized Example
1 public void run() {
2 synchronized (ts) {
3 ts.print(str1, str2);
4 }
5 }
6 }
7 class TestThread {
8 public static void main(String args[]) {
9 TwoStrings ts = new TwoStrings();
10 new PrintStringsThread("Hello ", "there.", ts);
11 new PrintStringsThread("How are ", "you?", ts);
12 new PrintStringsThread("Thank you ",
13 "very much!", ts);
14 }}
Introduction to Programming 2 39
Interthread Communication:
Methods
Introduction to Programming 2 40
Interthread Communication
Introduction to Programming 2 41
Producer-Consumer Example
1 class SharedData {
2 int data;
3 synchronized void set(int value) {
4 System.out.println("Generate " + value);
5 data = value;
6 }
7 synchronized int get() {
8 System.out.println("Get " + data);
9 return data;
10 }
11 }
12 //continued...
Introduction to Programming 2 42
Producer-Consumer Example
1 class Producer implements Runnable {
2 SharedData sd;
3 Producer(SharedData sd) {
4 this.sd = sd;
5 new Thread(this, "Producer").start();
6 }
7 public void run() {
8 for (int i = 0; i < 10; i++) {
9 sd.set((int)(Math.random()*100));
10 }
11 }
12 }
13 //continued...
Introduction to Programming 2 43
Producer-Consumer Example
1 class Consumer implements Runnable {
2 SharedData sd;
3 Consumer(SharedData sd) {
4 this.sd = sd;
5 new Thread(this, "Consumer").start();
6 }
7 public void run() {
8 for (int i = 0; i < 10 ; i++) {
9 sd.get();
10 }
11 }
12 }
13 //continued...
Introduction to Programming 2 44
Producer-Consumer Example
1 class TestProducerConsumer {
2 public static void main(String args[])
3 throws Exception {
4 SharedData sd = new SharedData();
5 new Producer(sd);
6 new Consumer(sd);
7 }
8 }
Introduction to Programming 2 45
Producer-Consumer Example
Sample output:
Generate 8 Get 35
Generate 45 Generate 39
Generate 52 Get 39
Generate 65 Generate 85
Get 65 Get 85
Generate 23 Get 85
Get 23 Get 85
Generate 49 Generate 35
Get 49 Get 35
Generate 35 Get 35
Introduction to Programming 2 46
Fixed Producer-Consumer
Example
1 class SharedData {
2 int data;
3 boolean valueSet = false;
4 synchronized void set(int value) {
5 if (valueSet) { //has just produced a value
6 try {
7 wait();
8 } catch (InterruptedException ie) {
9 }
10 }
11 //continued...
Introduction to Programming 2 47
Fixed Producer-Consumer
Example
1 System.out.println("Generate " + value);
2 data = value;
3 valueSet = true;
4 notify();
5 }
6 //continued...
Introduction to Programming 2 48
Fixed Producer-Consumer
Example
1 synchronized int get() {
2 if (!valueSet) {
3 //producer hasn't set a value yet
4 try {
5 wait();
6 } catch (InterruptedException ie) {
7 }
8 }
9 //continued...
Introduction to Programming 2 49
Fixed Producer-Consumer
Example
1 System.out.println("Get " + data);
2 valueSet = false;
3 notify();
4 return data;
5 }
6 }
Introduction to Programming 2 50
Producer-Consumer Example
Sample output:
Generate 76 Get 29
Get 76 Generate 26
Generate 25 Get 26
Get 25 Generate 86
Generate 34 Get 86
Get 34 Generate 65
Generate 84 Get 65
Get 84 Generate 38
Generate 48 Get 38
Get 48 Generate 46
Generate 29 Get 46
Introduction to Programming 2 51
Concurrency Utilities
Introduced in Java 2 SE 5.0
Found in the java.util.concurrent package
Interfaces
− Executor
− Callable
Introduction to Programming 2 52
The Executor Interface
(BEFORE) Executing Runnable tasks:
new Thread(<aRunnableObject>).start();
(AFTER) Executing Runnable tasks:
<anExecutorObject>.execute(<aRunnableObject>);
Introduction to Programming 2 53
The Executor Interface
Problems with the older technique:
− Thread creation is expensive.
Need stack and heap space
May cause out of memory errors
Remedy:
− Use thread pooling
Well-designed implementation is not simple
− Difficulty in cancellation and shutting down of threads
Introduction to Programming 2 54
The Executor Interface
Solution to problems with the older technique:
− Use the Executor interface
Decouples task submission from the mechanics of how each task will be run
Using the Executor interface:
Executor <executorName> = <anExecutorObject>;
<executorName>.execute(new <RunnableTask1>());
<executorName>.execute(new <RunnableTask2>());
...
Introduction to Programming 2 55
The Executor Interface
Creating an object of Executor type:
− Cannot be instantiated
− Can create a class implementing this interface
− Can use factory method provided in the Executors class
Executors also provides factory methods for simple thread pool management
Introduction to Programming 2 56
The Executors Factory
Methods
Introduction to Programming 2 57
The Executor Interface
Controls execution and completion of Runnable tasks
Killing threads:
executor.shutdown();
Introduction to Programming 2 58
The Callable Interface
Recall:
− Two way of creating threads:
Extend Thread class
Implement Runnable interface
− Should override the run method
public void run() //no throws clause
Callable interface
− Runnable interface without the drawbacks
Introduction to Programming 2 59
The Callable Interface
(BEFORE) Getting result from a Runnable task:
public MyRunnable implements Runnable {
private int result = 0;
public void run() {
...
result = someValue;
}
/* The result attribute is protected from changes
from other codes accessing this class */
public int getResult() {
return result;
}
} Introduction to Programming 2 60
The Callable Interface
(AFTER) Getting result from a Runnable task:
import java.util.concurrent.*;
Introduction to Programming 2 61
The Callable Interface
The call method
V call throws Exception
where
V is a generic type.
Other concurrency features still
− J2SE 5.0 API documentation
Introduction to Programming 2 62
Summary
Threads
− Thread Definition
− Thread States
Running
Ready to run
Resumed
Suspended
Blocked
− Priorities
Range from 1 to 10
Context switch
Introduction to Programming 2 63
Summary
The Thread Class
− Constructor
− Constants
MAX_PRIORITY
MIN_PRIORITY
NORM_PRIORITY
− Methods
currentThread() join([long millis, [int nanos]])
getName() sleep(long millis)
setName(String name) run()
getPriority() start()
isAlive()
Introduction to Programming 2 64
Summary
Creating Threads
− Extending the Thread Class
− Implementing the Runnable Interface
− Extending vs. Implementing
Synchronization
− Locking an Object
− The synchronized keyword
Method header
Object
Introduction to Programming 2 65
Summary
Interthread Communication
− Methods
wait
notify
notifyAll
Concurrency Utilities
− The Executor Interface
The Executors factory methods
− The Callable Interface
Introduction to Programming 2 66