Você está na página 1de 66

9 Threads

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 }

1 /* The remaining part of the code doesn't change. */

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.*;

public class MyCallable implements Callable {


public Integer call() throws java.io.IOException {
...
return someValue;
}
}

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

Você também pode gostar