deadlock victim

181
The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr Deadlock Victim by Dr Heinz Kabutz && Olivier Croisier The Java Specialists Newsletter && The Coder's Breakfast [email protected] && [email protected] 1

Upload: zenika

Post on 26-Jun-2015

1.668 views

Category:

Technology


0 download

DESCRIPTION

Support de la présentation "Deadlock Victim" à Devoxx-fr 2012, par Heinz Kabutz (javaspecialists.eu) et Olivier Croisier (zenika.com, thecodersbreakfast.net).

TRANSCRIPT

Page 1: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Deadlock Victimby Dr Heinz Kabutz && Olivier Croisier

The Java Specialists Newsletter && The Coder's Breakfast [email protected] && [email protected]

1

Page 2: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

You discover a race condition

2

Page 3: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Data is being corrupted

3

Page 4: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

What ya gonna do?

4

Page 5: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Who ya gonna call?

5

Page 6: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Ghostbusters?

6

Page 7: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

you do what we all do

7

Page 8: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

you use synchronized

8

Page 9: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

synchronized

9

Page 10: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

synchronized

9

Page 11: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

synchronized can be bad medicine

10

Page 12: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

deadlock awaits you!

11

Page 13: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

12

Page 14: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

13

Deadlock Victim

Page 15: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

14

Correctness fixcan lead to

liveness fault

Page 16: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

lock ordering deadlock

15

Page 17: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

16

at least two locks

Page 18: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

17

and at least two threads

Page 19: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

18

locked in different orders

Page 20: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

19

can cause a deadly embrace

Page 21: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

requires global analysis to fix

20

Page 22: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

resource deadlocks

21

Page 23: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

bounded queues

22

Page 24: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

bounded thread pools

23

Page 25: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

semaphores

24

Page 26: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

class loaders

25

Page 27: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

lost signals

26

Page 28: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

The Drinking Philosophers

27

Page 29: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

@ the Java Specialist Symposium in Crete

28

Page 30: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Symposium == sym + potoLiterally - to drink together

29

Page 31: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

our philosophers need two cups

30

Page 32: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

they either want to drink or think

31

Page 33: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Table is ready, all philosophers are thinking

32

1

25

4 3

Page 34: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

philosophers 5 wants to drink, takes right cup

33

1

25

4 3

Page 35: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 is now drinking with both cups

34

1

25

4 3

Page 36: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

philosophers 3 wants to drink, takes right cup

35

1

25

4 3

Page 37: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 is now drinking with both cups

36

1

25

4 3

Page 38: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

philosophers 2 wants to drink, takes right cup

37

1

25

4 3

Page 39: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 finished drinking, returns right cup

38

1

25

4 3

Page 40: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 is now drinking with both cups

39

1

5

4 3

2

Page 41: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 returns Left cup

40

1

25

4 3

Page 42: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

philosophers can get stuck

41

Page 43: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

if they all pick up the right cup

42

Page 44: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

A deadlock can easily happen with this design

43

1

25

4 3

Page 45: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 wants to drink, takes right cup

44

1

25

4 3

Page 46: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 1 wants to drink, takes right cup

45

1

25

4 3

Page 47: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 wants to drink, takes right cup

46

1

25

4 3

Page 48: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 wants to drink, takes right cup

47

1

25

4 3

Page 49: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 4 wants to drink, takes right cup

48

1

25

4 3

Page 50: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Deadlock!

49

1

25

4 3

Page 51: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

they will all stay thirsty

50

1

25

4 3

Page 52: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

this is a deadly embrace

51

1

25

4 3

Page 53: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

this can be detected automatically

52

Page 54: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

search the graph of call stacks

53

Page 55: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

and look for circular dependencies

54

Page 56: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

ThreadMXBean does that for us

55

Page 57: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

simple deadlocks are quickly found

56

Page 58: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but what do you DO with them?

57

Page 59: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

what will the dog do with the car if he ever catches it?

58

Page 60: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

databases choose deadlock victim

59

Page 61: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but what does Java do?

60

Page 62: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

it should probably throw an Error

61

Page 63: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but the threads simply hang up

62

Page 64: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

it is best to avoid causing them!

63

Page 65: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

global order of locks in program

64

Page 66: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

65

public class LeftRightDeadlock { private final Object left = new Object(); private final Object right = new Object(); public void leftRight() { synchronized (left) { synchronized (right) { doSomething(); } } } public void rightLeft() { synchronized (right) { synchronized (left) { doSomethingElse(); } } }}

Page 67: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Interleaving causes deadlock

66

A

B

lock left

lock right

leftRight()

rightLeft()

BLOCKED

trying to lock right

BLOCKED

trying to lock left

Page 68: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

we define a fixed global order

67

Page 69: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

e.g. left before right

68

Page 70: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

deadlock is solved!

69

public void rightLeft() { synchronized (left) { synchronized (right) { doSomethingElse(); } } }

Page 71: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

our drinking philosophers

70

Page 72: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

each cup gets a unique number

71

Page 73: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

lock the highest number cup first

72

Page 74: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

then lock the lower number cup

73

Page 75: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

drink

74

Page 76: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

unlock lower order cup

75

Page 77: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

unlock higher order cup

76

Page 78: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

think

77

Page 79: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Global Lock ordering

•We start with all thephilosophers thinking

78

1

25

4 34

3

21

5

Page 80: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 takes cup 5

• Cup 5 has higher number

• Remember our rule!

79

1

25

4 34

3

2

5

1

Page 81: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 1 takes cup 2

• Must take the cup withthe higher numberfirst

• In this casecup 2

80

1

25

4 34

3

2

5

1

Page 82: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 takes cup 3

81

1

25

4 34

3

2

5

1

Page 83: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 takes cup 4

82

1

25

4 34

3

2

5

1

Page 84: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 1 takes cup 1 - Drinking

83

1

25

4 34

3

2

5

1

Page 85: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 1 returns Cup 1• Cups are returned in the

opposite order to whatthey are acquired

84

1

25

4 34

3

2

5

1

Page 86: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 takes cup 1 - Drinking

85

1

25

4 34

3

2

5

1

Page 87: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 returns cup 1

86

1

25

4 34

3

2

5

1

Page 88: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 1 returns cup 2

87

1

25

4 34

3

2

5

1

Page 89: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 takes cup 2 - Drinking

88

1

25

4 34

3

2

5

1

Page 90: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 5 returns cup 5

89

1

25

4 34

3

2

5

1

Page 91: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 4 takes cup 5

90

1

25

4 34

3

2

5

1

Page 92: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 returns cup 2

91

1

25

4 34

2

5

1

3

Page 93: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 2 returns cup 3

92

1

25

4 4

5

1 2

3

3

Page 94: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 takes cup 3 - Drinking

93

1

25

4 34

3

2

5

1

Page 95: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 Returns cup 3

94

1

25

4 3

2

5

1

3

4

Page 96: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 3 Returns cup 4

95

1

25

3

2

5

1

4

4

3

Page 97: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 4 takes cup 4 - Drinking

96

1

25

4 34

3

2

5

1

Page 98: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 4 Returns cup 4

97

1

25

4 3

3

21

45

Page 99: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Philosopher 4 Returns cup 5

98

1

25

4 34

3

2

5

1

Page 100: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

sorting locks by property is easy

99

Page 101: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

e.g. account IBAN number

100

Page 102: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

or employee number

101

Page 103: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

or some other characteristic

102

Page 104: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

maybe even System.identityHashCode()

103

Page 105: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

use "open calls"

104

Page 106: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Vector synchronizes writeObject()

105

private synchronized void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();}

Page 107: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

synchronized writeObject() is invoking s.defaultWriteObject()

106

private synchronized void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();}

Page 108: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

this is not an "open call"

107

private synchronized void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();}

Page 109: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but can it cause problems?

108

private synchronized void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();}

Page 110: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

yes it can!

109

private synchronized void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject();}

Page 111: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

serialize both vectors at same time

110

Vector v1 = new Vector();Vector v2 = new Vector();v1.add(v2);v2.add(v1);

Page 112: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

this could happen with nested data structures

111

Page 113: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

it happened to an IBM client

112

Page 114: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

private void writeObject(ObjectOutputStream stream) throws IOException { Vector<E> cloned = null; // this specially fix is for a special dead-lock in customer // program: two vectors refer each other may meet dead-lock in // synchronized serialization. Refer CMVC-103316.1 synchronized (this) { try { cloned = (Vector<E>) super.clone(); cloned.elementData = elementData.clone(); } catch (CloneNotSupportedException e) { // no deep clone, ignore the exception } } cloned.writeObjectImpl(stream);}

private void writeObjectImpl(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject();}

113

Page 115: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

private void writeObject(ObjectOutputStream s) throws IOException { final ObjectOutputStream.PutField fields = s.putFields(); final Object[] data; synchronized (this) { fields.put("capacityIncrement", capacityIncrement); fields.put("elementCount", elementCount); data = elementData.clone(); } fields.put("elementData", data); s.writeFields();}

114

Java 7 uses an "open call"

Page 116: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

• File

• StringBuffer

• Throwable

• URL

• Hashtable

• and others

115

More synchronized writeObject()s

Page 117: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

we have seen the deadly embrace

116

Page 118: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

are there other deadlocks?

117

Page 119: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

semaphore deadlocks

118

Page 120: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Bounded DB Connection Pools

• For example, say you have two DB connection pools

• Some tasks might require connections to both databases

• Thus thread A might hold semaphore for D1 and wait for D2, whereas thread B might hold semaphore for D2 and be waiting for D1

119

Page 121: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

public class DatabasePool { private final Semaphore connections; public DatabasePool(int connections) { this.connections = new Semaphore(connections); }

public void connect() { connections.acquireUninterruptibly(); System.out.println("DatabasePool.connect"); }

public void disconnect() { System.out.println("DatabasePool.disconnect"); connections.release(); }}

120

Page 122: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

ThreadMXBean does not show this as a deadlock!

121

Page 123: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

JVM does not detect this deadlock

122

Page 124: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

JVM does not detect this deadlock

122

Page 125: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Avoiding and diagnosing deadlocksAvoiding Liveness Hazards

123

Page 126: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

124

Avoiding and diagnosing deadlocks

• You cannot get a lock-ordering deadlock with a single lock

• Easiest way to avoid deadlocks

• But not always practical

Page 127: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

125

Avoiding and diagnosing deadlocks

• For multiple locks we need to define a lock order

• specify and document possible lock sequences

• Identify where multiple locks could be acquired

• Do a global analysis to ensure that lock ordering is consistent

• This can be extremely difficult in large programs

Page 128: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Use open calls whenever possible

126

Page 129: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Unit Testing for lock ordering deadlocks

• Code typically has to be called many times before a deadlock happens

• How many times do you need to call it to prove that there is no deadlock?

• Nondeterministic unit tests are bad - they should either always pass or always fail

127

Page 130: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Testing the Bank

• In the transferMoney() method, a deadlock occurs if after the first lock is granted, the first thread is swapped out and another thread requests the second lock

128

public class Bank { public boolean transferMoney(Account from, Account to, Amount amount) { synchronized (from) { // if thread is swapped out here, we can end up with a deadlock synchronized (to) { return doActualTransfer(from, to, amount); } } }}

Page 131: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

We can force the context switch

129

Page 132: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

simply add a sleep after first lock

130

Page 133: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Adding a sleep to cause deadlocks

131

public class Bank { public boolean transferMoney(Account from, Account to, Amount amount) { synchronized (from) { sleepAWhileForTesting(); synchronized (to) { return doActualTransfer(from, to, amount); } } } protected void sleepAWhileForTesting() {}}

Page 134: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

In our unit test we use a SlowBank

132

public class SlowBank extends Bank { private final long timeout; private final TimeUnit unit; public SlowBank(long timeout, TimeUnit unit) { this.timeout = timeout; this.unit = unit; } protected void sleepAWhileForTesting() { try { unit.sleep(timeout); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }}

Page 135: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Won't this cause problems in production?

133

Page 136: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

In production we only use Bank

134

Page 137: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

HotSpot will optimize away empty sleepAWhileForTesting()

135

Page 138: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

it is thus a zero cost

136

Page 139: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

as long as SlowBank is never used

137

Page 140: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

How can you verify the lock-ordering deadlock?

138

Page 141: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

CTRL+Break, jstack, kill -3, jconsole, etc.

139

Page 142: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but that won't be a good unit test

140

Page 143: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Better via Java's ThreadMXBean

141

Page 144: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

ThreadMXBean

• Get instance with ManagementFactory.getThreadMXBean()

• findMonitorDeadlockedThreads()

• Includes only "monitor" locks, i.e. synchronized

• Only way to find deadlocks in Java 5

142

Page 145: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

ThreadMXBean

• Better is findDeadlockedThreads()

• Includes "monitor" and "owned" (Java 5) locks

• Preferred method to test for deadlocks

• But, does not find deadlocks between semaphores

• See http://www.javaspecialists.eu/archive/Issue130.html

143

Page 146: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

144

public class BankDeadlockTest { private final static ThreadMXBean tmb = ManagementFactory.getThreadMXBean();

private boolean isThreadDeadlocked(long tid) { long[] ids = tmb.findDeadlockedThreads(); if (ids == null) return false; for (long id : ids) { if (id == tid) return true; } return false; }

Page 147: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

145

private void checkThatThreadTerminates(Thread thread) throws InterruptedException { for (int i = 0; i < 2000; i++) { thread.join(50); if (!thread.isAlive()) return; if (isThreadDeadlocked(thread.getId())) { fail("Deadlock detected!"); } } fail(thread + " did not terminate in time"); }

Page 148: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

146

@Test public void testForTransferDeadlock() throws InterruptedException { final Account alpha = new Account(new Amount(1000)); final Account ubs = new Account(new Amount(1000000)); final Bank bank = new SlowBank(100, TimeUnit.MILLISECONDS);

Thread alphaToUbs = new Thread("alphaToUbs") { public void run() { bank.transferMoney(alpha, ubs, new Amount(100)); } }; Thread ubsToAlpha = new Thread("ubsToAlpha") { public void run() { bank.transferMoney(ubs, alpha, new Amount(100)); } };

alphaToUbs.start(); ubsToAlpha.start();

checkThatThreadTerminates(alphaToUbs); }}

Page 149: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

• We see the deadlock within about 100 milliseconds

147

Output with broken transferMoney() method

junit.framework.AssertionFailedError: Deadlock detected! at BankDeadlockTest.checkThatThreadTerminates(BankDeadlockTest.java:20) at BankDeadlockTest.testForTransferDeadlock(BankDeadlockTest.java:55)

Page 150: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

• If we fix the transferMoney() method, it also completes within about 100 milliseconds

• This is the time that we are sleeping for testing purposes

• Remember that the empty sleepAWhileForTesting() method will be optimized away by HotSpot

148

Output with broken transferMoney() method

Page 151: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Timed lock attempts

• Another technique for solving deadlocks is to use the timed tryLock() method of explicit Java locks

149

Page 152: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

However, if tryLock() fails it may be

150

Page 153: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

a deadlock

151

Page 154: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

or some thread taking a long time

152

Page 155: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

or a thread in an infinite loop

153

Page 156: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

But ThreadMXBean shows it as deadlocked

154

Page 157: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

even if it is a temporary condition

155

Page 158: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

The JVM has support for tryLock with synchronized

156

Page 159: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

but it is hidden away

157

Page 160: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

So here it is

158

Page 161: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

159

Page 162: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Told you it was hidden!

160

Page 163: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

It is hidden for a good reason

161

Page 164: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

if you need tryLock functionality

162

Page 165: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

rather use explicit locks (ReentrantLock)

163

Page 166: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

tryLock with synchronized

• Technically possible in Sun JVM using

• Unsafe.getUnsafe().tryMonitorEnter(monitor)

• Unsafe.getUnsafe().monitorExit(monitor)

• http://www.javaspecialists.eu/archive/Issue194.html

164

Page 167: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Deadlock analysis with thread dumps

165

Page 168: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Deadlock analysis with thread dumps

• We can also cause a thread dump in many ways:

• Ctrl+Break on Windows or Ctrl-\ on Unix

• Invoking "kill -3" on the process id

• Calling jstack on the process id

• Only shows deadlocks since Java 6

• Intrinsic locks show more information of where they were acquired

166

Page 169: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Can a deadlock be resolved?

167

Page 170: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

NO with synchronized

168

Page 171: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

YES with ReentrantLock

169

Page 172: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

synchronized() goes into BLOCKED state

170

Page 173: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

ReentrantLock.lock() goes into WAITING state

171

Page 174: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

We can write a DealockArbitrator

172

Page 175: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

This stops one of the threads with a DeadlockVictimError

173

Page 176: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Our special Error for deadlocks

174

public class DeadlockVictimError extends Error { private final Thread victim; public DeadlockVictimError(Thread victim) { super("Deadlock victim: " + victim); this.victim = victim;

} public Thread getVictim() { return victim; }}

Page 177: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

175

public class DeadlockArbitrator { private static final ThreadMXBean tmb = ManagementFactory.getThreadMXBean();

public boolean tryResolveDeadlock( int attempts, long timeout, TimeUnit unit) throws InterruptedException { for (int i = 0; i < attempts; i++) { long[] ids = tmb.findDeadlockedThreads(); if (ids == null) return true; Thread t = findThread(ids[i % ids.length]); if (t == null) throw new IllegalStateException("Could not find thread"); t.stop(new DeadlockVictimError(t)); unit.sleep(timeout); } return false; }

Page 178: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

finding threads by id is tricky

176

public boolean tryResolveDeadlock() throws InterruptedException { return tryResolveDeadlock(3, 1, TimeUnit.SECONDS); }

private Thread findThread(long id) { for (Thread thread : Thread.getAllStackTraces().keySet()) { if (thread.getId() == id) return thread; } return null; }}

Page 179: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

177

Page 180: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

• Only use in extreme circumstances

• Code that is outside your control and that deadlocks

• Where you cannot prevent the deadlock

• Remember, it only works with ReentrantLock

178

Applicability of DeadlockArbitrator

Page 181: Deadlock Victim

The Java Specialists' Newsletter - javaspecialists.eu / zenika.fr

Deadlock Victim Questions?by Dr Heinz Kabutz && Olivier Croisier

The Java Specialists Newsletter && The Coder's Breakfast [email protected] && [email protected]

179