Вы находитесь на странице: 1из 12

1

11. Multithreaded Applications

3/10/2018

John Roberts

2
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization

3
What is a process?

• An instance of a computer program that is being


executed

• Contains the program code, and its current activity:

• Machine code

• Memory (includes code, process specific data, call


stack, and heap)

• State (content of registers, Program Counter, Stack


Pointer, etc.)
4
What is a thread?

• The smallest sequence of programmed instructions that


can be managed independently by a schedule (typically
part of the OS)

• Contained within a process

• A single path of execution within a process

• Shares resources within a process

• Processes have their own address space, threads


share their address space

5
Processes vs. Threads

• Threads are “lightweight processes”

• Communication between threads is accomplished by


accessing shared memory, processes must use relatively
more expensive IPC (files, sockets, pipes)

• Context switches between threads are cheaper


(processes must swap out a memory space, thread
memory space is shared)

6
Multithreading
Multiple threads running on multiple processors

Thread 1

Thread 2

Thread 3

Multiple threads sharing a single CPU

Thread 1

Thread 2

Thread 3
7
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization

8
Thread class

• Java docs

• To create a new thread of execution, we can subclass


Thread, and implement the run method

9
Objective

• Create and execute three threads

• One prints the letter a 100 times

• One prints the letter b 100 times

• One prints the numbers from 1 to 100

• Github
10
LetterThread

1 public class LetterThread extends Thread {


2 private char character;
3
4 public LetterThread( char character ) {
5 this.character = character;
6 }
7
8 public void run() {
9 for( int counter = 0; counter < 100; counter++ ) {
10 System.out.print( this.character + " " );
11 }
12 }
13 }

11
CounterThread

1 public class CounterThread extends Thread {


2 public void run() {
3 for( int counter = 1; counter <= 100; counter++ ) {
4 System.out.print( counter + " " );
5 }
6 }
7 }

12 What will this print out when I run it? When I run it again?

Client
(make command cleans, compiles, and runs)
1 public class Client {
2 public static void main( String[] args ) {
3 LetterThread a = new LetterThread( 'a' );
4 LetterThread b = new LetterThread( 'b' );
5 CounterThread c = new CounterThread();
6
7 a.start();
8 b.start();
9 c.start();
10 }
11 }
13
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization

14
Runnable Interface

• Java docs

• To create a new thread of execution, we can implement


the Runnable interface, and implement the run method

• Create a new Thread with the Runnable instance

15
Objective

• Create and execute three threads

• One prints the letter a 100 times

• One prints the letter b 100 times

• One prints the numbers from 1 to 100

• Github
16
extend Thread vs. implement Runnable

• Why would we want to do one over the other?

17 r is reused, so any state in r can be shared among the two threads


extend Thread vs. implement Runnable
running it
• Why would we want to do one over the other?

• You can only extend only one class, constraining your class
design (rooting the class hierarchy at Thread)

• Runnables can be shared among Threads, allowing us to


access common resources

CustomThread a = new CustomThread();

CustomThread b = new CustomThread();


CustomRunnable r = new CustomRunnable();

new Thread( r ).start();

new Thread( r ).start();

18 No difference between this and LetterThread


LetterRunnable

1 public class LetterRunnable implements Runnable {


2 private char character;
3
4 public LetterRunnable( char character ) {
5 this.character = character;
6 }
7
8 public void run() {
9 for( int counter = 0; counter < 100; counter++ ) {
10 System.out.print( this.character + " " );
11 }
12 }
13 }
19 No difference between this and CounterThread
CounterRunnable

1 public class CounterRunnable implements Runnable {


2 public void run() {
3 for( int counter = 1; counter <= 100; counter++ ) {
4 System.out.print( counter + " " );
5 }
6 }
7 }

20 Stylistically, I’m not a fan of the temp variables, this could be made
Client
more concise (YMMV):

1 public class Client {


2
3
public static void main( String[] args ) {
LetterRunnable a = new LetterRunnable( 'a' );
new Thread( new LetterRunnable( ‘a’) ).start();
4 LetterRunnable b = new LetterRunnable( 'b' );
5 CounterRunnable c = new CounterRunnable();
6
7 new Thread( a ).start();
8 new Thread( b ).start();
9 new Thread( c ).start();
10 }
11 }

21
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization
22
Thread States

Thread Created
ready stop finished

resume, notify,
start run or notifyAll
stop, or complete stop
new yield, or time
expired

suspend, sleep,
running blocked
or wait

23
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization

24 Note that Thread implements runnable (so both Threads and


Controlling Threads
Runnables are runnables)
• void run()

Invoked by the Java runtime system to execute the
thread. You must override this method and provide the
code you want your thread to execute (but you will not
invoke this method!)

• void start()

Starts the thread, which causes the run() method to be
invoked. Called by the runnable object in the client class.
25
Controlling Threads

• static void sleep( long milliseconds )



throws InterruptedException

Puts the runnable object to sleep (temporarily cease
execution) for a specified time in milliseconds

• public final void join() throws


InterruptedException

Allows one thread to wait for the completion of another

26
Overview
• What is a thread?

• Thread class

• Runnable interface

• Thread states

• Controlling threads

• Synchronization

27 Showing the possible case where thread execution switches at each


Synchronization
time step
• Shared resources could become corrupted if accessed
simultaneously by multiple threads

time balance thread A thread B

1 0 newBalance = bank.getBalance() +1

2 0 newBalance = bank.getBalance() +1

3 1 bank.setBalance( newBalance );

4 1 bank.setBalance( newBalance );
28
Piggy Bank

1 public class PiggyBank {


2 private int balance = 0;
3
4 public int getBalance() {
5 return this.balance;
6 }
7
8 public void setBalance( int newBalance ) {
9 this.balance = newBalance;
10 }
11 }

29 https://github.com/sfsu-csc-413-roberts/lecture-11/tree/master/piggy-
Add a Penny Thread, Unsynchronized
bank

1 public class AddAPennyThreadUnsynchronized extends Thread {


2
3
private PiggyBank bank; Arbitrary sleep to force interruption…
4 public AddAPennyThreadUnsynchronized( PiggyBank bank ) {
5 this.bank = bank;
6 }
7
8 public void run() {
9 int newBalance = bank.getBalance() + 1;
10
11 try {
12 Thread.sleep( 5 );
13 } catch( InterruptedException e ) {
14 System.out.println( "Interrupted" );
15 }
16
17 bank.setBalance( newBalance );
18 }
19 }

30
Synchronized Methods

• Java Tutorial

• To make a method synchronized, add the synchronized


keyword to its declaration:

public synchronized void someMethod() { /* … /* }

• When one thread is executing a synchronized method for


an object, all other threads that invoke synchronized
methods for the same object will block (suspend execution)

• Constructors can not be synchronized!


31
Locks

• Every object has an intrinsic lock associated with it

• Enforces exclusive access to an object’s state

• A thread that needs exclusive and consistent access to


an object’s state has to acquire the lock before
accessing them

• If another thread has already acquired the lock, then


the current thread must wait until the lock is released

• A thread releases the lock when done

32
Locks

• The intrinsic lock used with a synchronized method


controls only access to the current object

• We may also use the lock on the Class object associated


with the class, with a static synchronized method
declaration (see next slide)

33 Line 14 means that the *current thread* (main) should wait for
PiggyBank Driver
pennies[i] to complete - this line tells the current thread to wait until all
penny threads have completed execution.
1 public class PiggyBankDriver {
2 public static void main( String[] args ) throws InterruptedException {
3 final int count = 100;
4
5 PiggyBank bank = new PiggyBank();
6 Thread pennies[] = new Thread[ count ];
7
8 for( int i = 0; i < count; i++ ) {
9 pennies[ i ] = new AddAPennyThread( bank );
10 pennies[ i ].start();
11 }
12
13 for( int i = 0; i < count; i++ ) {
14 pennies[ i ].join();
15 }
16
17 System.out.println(
18 "After adding " + count + " pennies, balance is " + bank.getBalance()
19 );
20 }
21 }
34 https://github.com/sfsu-csc-413-roberts/lecture-11/tree/master/piggy-
Add a Penny Thread, with Synchronization
1 public class AddAPennyThreadSynchronized extends Thread {
bank-synchronized

static synchronized is using a lock obtained from the class - what


2 private PiggyBank bank;
3
4 public AddAPennyThreadSynchronized( PiggyBank bank ) {
5 this.bank = bank;
6
7
}
happens if we omit static (and change the run method accordingly)?

8 private static synchronized void addAPenny( PiggyBank bank ) {


9
10
11
int newBalance = bank.getBalance() + 1;

try {
Synchronization is happening on the thread, not on the PiggyBank
object! (We could change the implementation of PiggyBank for more
12 Thread.sleep( 5 );
13 } catch( InterruptedException e ) {
14 System.out.println( "Interrupted" );
15 }
16
17
18 }
bank.setBalance( newBalance ); intuitive access control…)
19
20 public void run() {
21 addAPenny( this.bank );
22 }
23 }

35 Guess which one is synchronized


Sample Outputs

ᐅ make
find . -type f -name '*.class' -delete
javac PiggyBankDriver.java; java PiggyBankDriver
After adding 100 pennies, balance is 1
ᐅ make
find . -type f -name '*.class' -delete
javac PiggyBankDriver.java; java PiggyBankDriver
After adding 100 pennies, balance is 2

ᐅ make
find . -type f -name '*.class' -delete
javac PiggyBankDriver.java; java PiggyBankDriver
After adding 100 pennies, balance is 100

Вам также может понравиться