Top Banner
Internet Software Internet Software Development Development Understanding Thread Safety Understanding Thread Safety Paul Krause Paul Krause
26

Internet Software Development

Feb 10, 2016

Download

Documents

malini

Internet Software Development. Understanding Thread Safety Paul Krause. Lecture 9. Contents A bit more on Locks Deadlock Race conditions Starvation Non-atomic operations. Locks. Every object has a lock You lock an object by synchronizing on it public void addElement(Object item) { - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Internet Software Development

Internet Software Internet Software DevelopmentDevelopment

Understanding Thread SafetyUnderstanding Thread SafetyPaul KrausePaul Krause

Page 2: Internet Software Development

Lecture 9Lecture 9

ContentsContents A bit more on LocksA bit more on Locks DeadlockDeadlock Race conditionsRace conditions StarvationStarvation Non-atomic operationsNon-atomic operations

Page 3: Internet Software Development

LocksLocks Every object has a lockEvery object has a lock

You lock an object by synchronizing on itYou lock an object by synchronizing on itpublic void addElement(Object item) {public void addElement(Object item) {

synchroniized(myArrayList) {synchroniized(myArrayList) {// do the stuff// do the stuff}}

}}public boolean elementExists(Object item) {public boolean elementExists(Object item) {

return myArrayList.contains(item)return myArrayList.contains(item)}}

To be absolutely accurate, synchronize on To be absolutely accurate, synchronize on access methods tooaccess methods too

Page 4: Internet Software Development

What to Lock?What to Lock?public class McBurgerPlace {public class McBurgerPlace {

private static Person ceo = new Person();private static Person ceo = new Person();private Object floor;private Object floor;private Object sodaFountain;private Object sodaFountain;

public static synchronized Person receiveCeo() {public static synchronized Person receiveCeo() {return ceo;return ceo;}}

public synchronized void waxFloor() {// do stuff … }public synchronized void waxFloor() {// do stuff … }

public Object getSodaFountain() {public Object getSodaFountain() {synchronized(sodaFountain) { // do stuff … }synchronized(sodaFountain) { // do stuff … }}}

}}

Page 5: Internet Software Development

Non-implicit lockingNon-implicit locking If If threadAthreadA is receiving the is receiving the ceoceo, can , can threadBthreadB wax the floor? wax the floor?

If If threadBthreadB is waxing the floor, can is waxing the floor, can threadCthreadC get the soda fountain? get the soda fountain?

The answer is Yes in both casesThe answer is Yes in both cases The JVM doesn’t do nested lockingThe JVM doesn’t do nested locking

Page 6: Internet Software Development

Locking objects not membersLocking objects not memberspublic class LockObjectNotMemberVariables {public class LockObjectNotMemberVariables { private List myList = new ArrayList();private List myList = new ArrayList(); public static void main(String[] args) {public static void main(String[] args) { LockObjectNotMemberVariables lonmv LockObjectNotMemberVariables lonmv

= new LockObjectNotMemberVariables();= new LockObjectNotMemberVariables(); lonmv.lockTest();lonmv.lockTest(); }} public synchronized void lockTest() {public synchronized void lockTest() { System.out.println("Is THIS object locked? " + System.out.println("Is THIS object locked? " +

Thread.holdsLock(this));Thread.holdsLock(this)); System.out.println("Is the list object locked? " +System.out.println("Is the list object locked? " +

Thread.holdsLock(myList));Thread.holdsLock(myList)); } } }}

Page 7: Internet Software Development

Locking objects not membersLocking objects not membersinit:init:deps-jar:deps-jar:Created dir: Created dir:

/Users/paulkrause/Java/threading/build/classes/Users/paulkrause/Java/threading/build/classesCompiling 1 source file to Compiling 1 source file to

/Users/paulkrause/Java/threading/build/classes/Users/paulkrause/Java/threading/build/classescompile-single:compile-single:run-single:run-single:Is THIS object locked? trueIs THIS object locked? trueIs the list object locked? falseIs the list object locked? falseBUILD SUCCESSFUL (total time: 4 seconds)BUILD SUCCESSFUL (total time: 4 seconds)

Page 8: Internet Software Development

Locking classes not Locking classes not instancesinstances

public class ClassLockNotObjectLock {public class ClassLockNotObjectLock { public static void main(String[] args) {public static void main(String[] args) { lockTest();lockTest(); }} public static synchronized void lockTest() {public static synchronized void lockTest() { ClassLockNotObjectLock clnol ClassLockNotObjectLock clnol

= new ClassLockNotObjectLock();= new ClassLockNotObjectLock(); System.out.println("Is the Class locked? " System.out.println("Is the Class locked? "

+ Thread.holdsLock(clnol.getClass()));+ Thread.holdsLock(clnol.getClass())); System.out.println("Is the object instance System.out.println("Is the object instance

locked? " + Thread.holdsLock(clnol));locked? " + Thread.holdsLock(clnol)); } } }}

Page 9: Internet Software Development

Locking classes not Locking classes not instancesinstances

init:init:deps-jar:deps-jar:Compiling 1 source file to Compiling 1 source file to

/Users/paulkrause/Java/threading/build/classes/Users/paulkrause/Java/threading/build/classescompile-single:compile-single:run-single:run-single:Is the Class locked? trueIs the Class locked? trueIs the object instance locked? falseIs the object instance locked? falseBUILD SUCCESSFUL (total time: 4 seconds)BUILD SUCCESSFUL (total time: 4 seconds)

Page 10: Internet Software Development

What to lock?What to lock? Synchronising on Objects other than Synchronising on Objects other than

““thisthis” provides more concurrency” provides more concurrency But controlling locks on such a fine scale But controlling locks on such a fine scale

can be inefficient if a method needs to can be inefficient if a method needs to access several objectsaccess several objects

The safest general policy is not to allow The safest general policy is not to allow unsynchronized access to the resources unsynchronized access to the resources you need to lock and synchronize methodsyou need to lock and synchronize methods

Page 11: Internet Software Development

Thread Safety ExamplesThread Safety Examples DeadlockDeadlock

First thread gets Lock 1 and then tries to get First thread gets Lock 1 and then tries to get Lock 2Lock 2

Second thread gets Lock 2 and then tries to Second thread gets Lock 2 and then tries to get Lock 1get Lock 1

Race ConditionsRace Conditions Two threads race for a common objectTwo threads race for a common object

StarvationStarvation A thread is never/rarely allowed to executeA thread is never/rarely allowed to execute

Page 12: Internet Software Development

DeadlockDeadlockpublic void run() {public void run() {

String name = Thread.currentThread().getName();String name = Thread.currentThread().getName();synchronized(lockA) {synchronized(lockA) {System.out.println(name + ": locked" + lockA);System.out.println(name + ": locked" + lockA);delay(name);delay(name);System.out.println(name + ": trying to get " System.out.println(name + ": trying to get " + lockB);+ lockB);synchronized(lockB) {synchronized(lockB) {System.out.println(name + ": locked" System.out.println(name + ": locked" + lockB);+ lockB);

}} }} }}

Page 13: Internet Software Development

Example runExample runinit:init:deps-jar:deps-jar:Compiling 1 source file to Compiling 1 source file to

/Users/paulkrause/Java/threading/build/classes/Users/paulkrause/Java/threading/build/classescompile-single:compile-single:run-single:run-single:Thread-0: lockedLock 1Thread-0: lockedLock 1Thread-0: delaying 1 secondThread-0: delaying 1 secondThread-1: lockedLock 2Thread-1: lockedLock 2Thread-1: delaying 1 secondThread-1: delaying 1 secondThread-0: trying to get Lock 2Thread-0: trying to get Lock 2Thread-1: trying to get Lock 1 Thread-1: trying to get Lock 1 Both threads now blocked Both threads now blocked

Page 14: Internet Software Development

Race condition exampleRace condition exampleif (Math.random() > .5) {if (Math.random() > .5) {

peter.start();peter.start();paul.start();paul.start();

} else {} else { paul.start();paul.start(); peter.start();peter.start(); }}

Page 15: Internet Software Development

Race condition exampleRace condition examplepublic void run() {public void run() {

System.out.println(getName() + ": trying for lock on " System.out.println(getName() + ": trying for lock on " + server);+ server);synchronized(server) {synchronized(server) {System.out.println(getName() + ": has lock on " System.out.println(getName() + ": has lock on " + server);+ server);// wait 2 seconds: show the other thread is really // wait 2 seconds: show the other thread is really // blocked// blockedtry {try {Thread.sleep(2000);Thread.sleep(2000);} catch (InterruptedException ie) {} catch (InterruptedException ie) {ie.printStackTrace();ie.printStackTrace();}}System.out.println(getName() + System.out.println(getName() + ": releasing lock ");": releasing lock ");

}}

Page 16: Internet Software Development

Example run (I)Example run (I)run-single:run-single:Peter: trying for lock on the common objectPeter: trying for lock on the common objectPeter: has lock on the common objectPeter: has lock on the common objectPaul: trying for lock on the common objectPaul: trying for lock on the common objectPeter: releasing lock Peter: releasing lock Paul: has lock on the common objectPaul: has lock on the common objectPaul: releasing lock Paul: releasing lock BUILD SUCCESSFUL (total time: 5 seconds)BUILD SUCCESSFUL (total time: 5 seconds)

Page 17: Internet Software Development

Example run (II)Example run (II)run-single:run-single:Paul: trying for lock on the common objectPaul: trying for lock on the common objectPaul: has lock on the common objectPaul: has lock on the common objectPeter: trying for lock on the common objectPeter: trying for lock on the common objectPaul: releasing lock Paul: releasing lock Peter: has lock on the common objectPeter: has lock on the common objectPeter: releasing lock Peter: releasing lock BUILD SUCCESSFUL (total time: 8 seconds)BUILD SUCCESSFUL (total time: 8 seconds)

Page 18: Internet Software Development

Starvation ExampleStarvation Examplefor (int i = 0; i < 4; i++) {for (int i = 0; i < 4; i++) {

// create a runner// create a runnerRunner r = new Runner();Runner r = new Runner();r.setPriority(Thread.MAX_PRIORITY);r.setPriority(Thread.MAX_PRIORITY);

// set the first thread to starve// set the first thread to starveif (i == 0) {if (i == 0) {

r.setPriority(Thread.MIN_PRIORITY);r.setPriority(Thread.MIN_PRIORITY);r.setName("Starvation Thread");r.setName("Starvation Thread");

}}// start the thread// start the threadr.start();r.start();r.yield(); // optional liner.yield(); // optional line

}}

Page 19: Internet Software Development

Example runExample runrun-single:run-single:Starvation Thread: is working 10Starvation Thread: is working 10Thread-1: is working 10Thread-1: is working 10Thread-2: is working 10Thread-2: is working 10Thread-1: is working 9Thread-1: is working 9Thread-2: is working 9Thread-2: is working 9Thread-1: is working 8Thread-1: is working 8Thread-2: is working 8Thread-2: is working 8Thread-1: is working 7Thread-1: is working 7Thread-2: is working 7Thread-2: is working 7Thread-1: is working 6Thread-1: is working 6Thread-2: is working 6Thread-2: is working 6Thread-1: is working 5Thread-1: is working 5Thread-2: is working 5Thread-2: is working 5Thread-1: is working 4Thread-1: is working 4Thread-2: is working 4Thread-2: is working 4Thread-1: is working 3Thread-1: is working 3Thread-2: is working 3Thread-2: is working 3Thread-1: is working 2Thread-1: is working 2Thread-2: is working 2Thread-2: is working 2Thread-1: is working 1Thread-1: is working 1Thread-2: is working 1Thread-2: is working 1

Thread-3: is working 10Thread-3: is working 10Thread-3: is working 9Thread-3: is working 9Thread-3: is working 8Thread-3: is working 8Thread-3: is working 7Thread-3: is working 7Thread-3: is working 6Thread-3: is working 6Thread-3: is working 5Thread-3: is working 5Thread-3: is working 4Thread-3: is working 4Thread-3: is working 3Thread-3: is working 3Thread-3: is working 2Thread-3: is working 2Thread-3: is working 1Thread-3: is working 1Starvation Thread: is working 9Starvation Thread: is working 9Starvation Thread: is working 8Starvation Thread: is working 8Starvation Thread: is working 7Starvation Thread: is working 7Starvation Thread: is working 6Starvation Thread: is working 6BUILD SUCCESSFUL (total time: 1 second)BUILD SUCCESSFUL (total time: 1 second)

Page 20: Internet Software Development

Atomic OperationsAtomic Operations Synchronization blocks some code as Synchronization blocks some code as

“atomic”“atomic” A thread will not be swapped out in the A thread will not be swapped out in the

middle of an atomic operationmiddle of an atomic operation Be careful in assuming any statements are Be careful in assuming any statements are

atomic!atomic!

Page 21: Internet Software Development

Non-atomic operationsNon-atomic operations x = 45;x = 45; Is atomic if x is an intIs atomic if x is an int Is not atomic if x is double or longIs not atomic if x is double or long

One operation for the high 32 bits, one for the One operation for the high 32 bits, one for the low 32 bitslow 32 bits

Page 22: Internet Software Development

Non-atomic operationsNon-atomic operations TreatTreat

x = 7;x = 7;y = x++;y = x++;

AsAsx = 7;x = 7;int temp = x + 1;int temp = x + 1;x = temp;x = temp;y = x;y = x;

A thread swap herecould lead to unexpected results

Page 23: Internet Software Development

Class NonAtomic.javaClass NonAtomic.java Class has a static variableClass has a static variable

static int x;static int x; The start ten threads that each do the following:The start ten threads that each do the following:for (int i= 0; i < 10; i++) {for (int i= 0; i < 10; i++) {

int reference = (int) (Math.random() * 100);int reference = (int) (Math.random() * 100);x = reference; x = reference;

// some calculation to make a slight delay // some calculation to make a slight delay if (x == reference) {if (x == reference) {validCounts++;validCounts++;

} else {} else { invalidCounts++;invalidCounts++;

}}}}

Page 24: Internet Software Development

Example runExample runrun-single:run-single:Thread-1 valid: 10 invalid: 0Thread-1 valid: 10 invalid: 0Thread-6 valid: 10 invalid: 0Thread-6 valid: 10 invalid: 0Thread-0 valid: 9 invalid: 1Thread-0 valid: 9 invalid: 1Thread-3 valid: 7 invalid: 3Thread-3 valid: 7 invalid: 3Thread-7 valid: 8 invalid: 2Thread-7 valid: 8 invalid: 2Thread-8 valid: 7 invalid: 3Thread-8 valid: 7 invalid: 3Thread-4 valid: 5 invalid: 5Thread-4 valid: 5 invalid: 5Thread-9 valid: 8 invalid: 2Thread-9 valid: 8 invalid: 2Thread-2 valid: 6 invalid: 4Thread-2 valid: 6 invalid: 4Thread-5 valid: 6 invalid: 4Thread-5 valid: 6 invalid: 4BUILD SUCCESSFUL (total time: 3 seconds)BUILD SUCCESSFUL (total time: 3 seconds)

Page 25: Internet Software Development

Problem fixedProblem fixedfor (int i= 0; i < 10; i++) {for (int i= 0; i < 10; i++) {

synchronized(NonAtomic.class) {synchronized(NonAtomic.class) {int reference = (int) (Math.random() * 100);int reference = (int) (Math.random() * 100);x = reference;x = reference;

// Do something intensive here// Do something intensive here

if (x == reference) {if (x == reference) {

validCounts++;validCounts++;} else {} else {

invalidCounts++;invalidCounts++;}}

}}

Page 26: Internet Software Development

New runNew runrun-single:run-single:Thread-0 valid: 10 invalid: 0Thread-0 valid: 10 invalid: 0Thread-7 valid: 10 invalid: 0Thread-7 valid: 10 invalid: 0Thread-2 valid: 10 invalid: 0Thread-2 valid: 10 invalid: 0Thread-1 valid: 10 invalid: 0Thread-1 valid: 10 invalid: 0Thread-5 valid: 10 invalid: 0Thread-5 valid: 10 invalid: 0Thread-3 valid: 10 invalid: 0Thread-3 valid: 10 invalid: 0Thread-8 valid: 10 invalid: 0Thread-8 valid: 10 invalid: 0Thread-6 valid: 10 invalid: 0Thread-6 valid: 10 invalid: 0Thread-9 valid: 10 invalid: 0Thread-9 valid: 10 invalid: 0Thread-4 valid: 10 invalid: 0Thread-4 valid: 10 invalid: 0BUILD SUCCESSFUL (total time: 3 seconds)BUILD SUCCESSFUL (total time: 3 seconds)