threading and concurrency issues ● creating threads ● in java ● subclassing thread ●...

14
Threading and Concurrency Issues Creating Threads In Java Subclassing Thread Implementing Runnable Synchronization Immutable Synchronized Methods Synchronized Blocks Performance Issues Thread Pooling Transactions and Threading Thread safety issues Thread-safe Immutable Thread-hostile

Upload: kelley-mccarthy

Post on 12-Jan-2016

223 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Threading and Concurrency Issues

● Creating Threads● In Java

● Subclassing Thread● Implementing Runnable

● Synchronization● Immutable● Synchronized Methods● Synchronized Blocks● Performance Issues

● Thread Pooling● Transactions and Threading● Thread safety issues

● Thread-safe● Immutable● Thread-hostile

Page 2: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Creating Threads

● In Java, there are two options:● Subclass the Thread class● Implement Runnable

● Subclassing is usually the poorest choice because you force the threaded class into an inheritance hierarchy.

● The most flexible solution is to implement Runnable.

Page 3: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Thread1

Thread Object

start() Thread2

run()

public class Test extends Thread{

// The start method is defined in the// Thread class. When called, it creates// a new thread and the new thread invokes// “run” on the current objectpublic void run(){

// This method runs in its// own thread

}}

Subclassing Thread

Page 4: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Runnable Object

public class Test implements Runnable{

private Thread theThread;

public void start(){

if (theThread == null){

theThread = new Thread(this);theThread.start();

}}

public void run(){

// This method runs in its// own thread

}

Thread1

Thread Objectstart()

Thread2run() run()

start()Thread(Runnable)

Implementing Runnable

create

Page 5: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Terminating Threads

● When Java was first introduced, the multi-threading library offered a method called stop().

● This method was invoked to stop a thread.

● However, it turned out that use of the stop method could lead to deadlock conditions

● When the stop method was invoked the thread would stop immediately and it wasn't given the opportunity to release any resources that it held.

● Uncontrolled stopping of a thread would give rise to unsafe conditions.

● The correct way to terminate a thread is for the thread to return from the “run” method

● This is usually accomplished through setting a boolean variable which is periodically checked within the run method.

Page 6: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

public class Test implements Runnable{

private Thread theThread;private boolean stopThread = false;

public void start(){

if (theThread == null){

theThread = new Thread(this);theThread.start();

}}

public void setStopThread(boolean aValue){

stopThread = aValue;}

public void run(){

while(!stopThread){

// ...}

}

Terminating Threads

Page 7: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Synchronization

● As you learned in CPSC 457, multi-threaded applications are subject to concurrency problems

● When two threads attempt to update the same data at the same time, the execution of the threads can become interleaved which gives rise to race conditions

● Race conditions can cause erroneous results in computation

● To prevent corruption, the programmer must identify shared variables.

● Access to these variables must be mutually exclusive in time between threads

● ie. only one thread may update a shared variable at any given point in time

● Java provides a “synchronized” keyword which is used to guarantee mututal exclusion in time.

Page 8: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Object monitors

● In order to accomplish mutual exclusion, each object in java is provided with a monitor (or lock).

● The lock cannot be directly accessed, it can only be access through the use of the synchronized keyword.

● If a method or block is synchronized, then a thread may not enter the method or block until it has obtained the monitor.

● If a thread cannot obtain the lock for the given method or block, it becomes blocked by the scheduler until such time that the monitor becomes available

● The testing and setting of the monitor is guaranteed to be atomic.

Page 9: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Synchronized methods

● The easiest way of obtaining mutual exclusion in Java is by defining methods as synchronized.

● If a method is synchronized, the monitor of the target object is obtained.

● It is possible to define multiple synchronized methods within a class.

● This guarantees that only one thread may be executing any of the synchronized methods at a give point in time.

public class SavingsAccount{

private float balance;

public synchronized void withdraw(float anAmount){

if ((anAmount>0.0) && (anAmount<=balance))balance = balance - anAmount;

}

public synchronized void deposit(float anAmount){

if (anAmount>0.0)balance = balance + anAmount;

}

Page 10: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Synchronization and performance

● Unfortunately, synchronization comes with a price. ● Performance suffers because threads which could be executing are blocked if another thread is currently executing a synchronized method on the target object.

● The solution to this problem is to make the area which is synchronized as small as possible

● Methods do not offer fine enough granularity.● It is possible to synchronize blocks instead of whole methods.

Page 11: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Synchronized blocks

public class SavingsAccount{private float balance;

public void withdraw(float anAmount){

if (anAmount<0.0)throw new IllegalArgumentException("Withdraw amount negative");

synchronized(this){

if (anAmount<=balance)balance = balance - anAmount;

}}

public void deposit(float anAmount){

if (anAmount<0.0)throw new IllegalArgumentException("Deposit amount negative");

synchronized(this){

balance = balance + anAmount;}

}

Page 12: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Synchronized blocks and methods:

● This method:

is equivalent to this method:

public synchronized void withdraw(float anAmount){

if ((anAmount>0.0) && (anAmount<=balance))balance = balance - anAmount;

}

public void withdraw(float anAmount){

synchronized(this){

if ((anAmount>0.0) && (anAmount<=balance))balance = balance – anAmount;

}}

Page 13: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

Other performance considerations

● While the creation of threads is a relatively inexpensive operation (particularly when compared to creating processes), there is still an overhead should an application be creating and terminating a large number of threads.

● One general solution is to create a thread pool:● References to the Runnable objects are kept in a collection and pulled out when needed

● Runnable objects obtain their work (in the form of transactions) from a queue. If no work is available, the thread blocks.

Page 14: Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized

General Threading Considerations

● Avoid over-synchronization● Don't write code which depends on how the scheduler is going to behave

● Always invoke wait within a loop● Never use thread groups● Never use stop() or resume()● Document Thread Safety

● Immutable: Data cannot change. No external synchronization is necessary

● Thread-safe: instance of the class are mutable, but the methods contain sufficient internal synchronization so that the methods can be used without any external synchronization

● Conditionally thread-safe: Some methods must be invoked in a specific order or external synchronization must be provided.

● Thread-compatible: Instances can be used concurrently provided that each method is protected by external synchronization

● Thread-hostile: cannot be used concurrently, even if external synchronization is provided.