Deadlock Victim

Post on 26-Jun-2015

1.657 views 0 download

Tags:

description

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

Transcript of 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 heinz@javaspecialists.eu && olivier.croisier@zenika.com

1

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

You discover a race condition

2

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

Data is being corrupted

3

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

What ya gonna do?

4

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

Who ya gonna call?

5

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

Ghostbusters?

6

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

you do what we all do

7

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

you use synchronized

8

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

synchronized

9

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

synchronized

9

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

synchronized can be bad medicine

10

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

deadlock awaits you!

11

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

12

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

13

Deadlock Victim

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

14

Correctness fixcan lead to

liveness fault

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

lock ordering deadlock

15

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

16

at least two locks

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

17

and at least two threads

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

18

locked in different orders

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

19

can cause a deadly embrace

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

requires global analysis to fix

20

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

resource deadlocks

21

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

bounded queues

22

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

bounded thread pools

23

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

semaphores

24

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

class loaders

25

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

lost signals

26

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

The Drinking Philosophers

27

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

@ the Java Specialist Symposium in Crete

28

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

Symposium == sym + potoLiterally - to drink together

29

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

our philosophers need two cups

30

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

they either want to drink or think

31

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

Table is ready, all philosophers are thinking

32

1

25

4 3

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

philosophers 5 wants to drink, takes right cup

33

1

25

4 3

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

Philosopher 5 is now drinking with both cups

34

1

25

4 3

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

philosophers 3 wants to drink, takes right cup

35

1

25

4 3

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

Philosopher 3 is now drinking with both cups

36

1

25

4 3

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

philosophers 2 wants to drink, takes right cup

37

1

25

4 3

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

Philosopher 3 finished drinking, returns right cup

38

1

25

4 3

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

Philosopher 2 is now drinking with both cups

39

1

5

4 3

2

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

Philosopher 3 returns Left cup

40

1

25

4 3

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

philosophers can get stuck

41

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

if they all pick up the right cup

42

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

A deadlock can easily happen with this design

43

1

25

4 3

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

Philosopher 5 wants to drink, takes right cup

44

1

25

4 3

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

Philosopher 1 wants to drink, takes right cup

45

1

25

4 3

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

Philosopher 2 wants to drink, takes right cup

46

1

25

4 3

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

Philosopher 3 wants to drink, takes right cup

47

1

25

4 3

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

Philosopher 4 wants to drink, takes right cup

48

1

25

4 3

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

Deadlock!

49

1

25

4 3

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

they will all stay thirsty

50

1

25

4 3

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

this is a deadly embrace

51

1

25

4 3

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

this can be detected automatically

52

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

search the graph of call stacks

53

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

and look for circular dependencies

54

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

ThreadMXBean does that for us

55

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

simple deadlocks are quickly found

56

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

but what do you DO with them?

57

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

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

58

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

databases choose deadlock victim

59

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

but what does Java do?

60

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

it should probably throw an Error

61

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

but the threads simply hang up

62

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

it is best to avoid causing them!

63

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

global order of locks in program

64

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(); } } }}

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

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

we define a fixed global order

67

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

e.g. left before right

68

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

deadlock is solved!

69

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

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

our drinking philosophers

70

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

each cup gets a unique number

71

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

lock the highest number cup first

72

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

then lock the lower number cup

73

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

drink

74

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

unlock lower order cup

75

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

unlock higher order cup

76

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

think

77

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

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

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

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

Philosopher 2 takes cup 3

81

1

25

4 34

3

2

5

1

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

Philosopher 3 takes cup 4

82

1

25

4 34

3

2

5

1

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

Philosopher 1 takes cup 1 - Drinking

83

1

25

4 34

3

2

5

1

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

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

Philosopher 5 takes cup 1 - Drinking

85

1

25

4 34

3

2

5

1

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

Philosopher 5 returns cup 1

86

1

25

4 34

3

2

5

1

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

Philosopher 1 returns cup 2

87

1

25

4 34

3

2

5

1

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

Philosopher 2 takes cup 2 - Drinking

88

1

25

4 34

3

2

5

1

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

Philosopher 5 returns cup 5

89

1

25

4 34

3

2

5

1

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

Philosopher 4 takes cup 5

90

1

25

4 34

3

2

5

1

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

Philosopher 2 returns cup 2

91

1

25

4 34

2

5

1

3

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

Philosopher 2 returns cup 3

92

1

25

4 4

5

1 2

3

3

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

Philosopher 3 takes cup 3 - Drinking

93

1

25

4 34

3

2

5

1

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

Philosopher 3 Returns cup 3

94

1

25

4 3

2

5

1

3

4

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

Philosopher 3 Returns cup 4

95

1

25

3

2

5

1

4

4

3

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

Philosopher 4 takes cup 4 - Drinking

96

1

25

4 34

3

2

5

1

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

Philosopher 4 Returns cup 4

97

1

25

4 3

3

21

45

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

Philosopher 4 Returns cup 5

98

1

25

4 34

3

2

5

1

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

sorting locks by property is easy

99

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

e.g. account IBAN number

100

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

or employee number

101

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

or some other characteristic

102

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

maybe even System.identityHashCode()

103

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

use "open calls"

104

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

Vector synchronizes writeObject()

105

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

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();}

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();}

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

but can it cause problems?

108

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

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

yes it can!

109

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

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);

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

this could happen with nested data structures

111

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

it happened to an IBM client

112

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

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"

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

• File

• StringBuffer

• Throwable

• URL

• Hashtable

• and others

115

More synchronized writeObject()s

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

we have seen the deadly embrace

116

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

are there other deadlocks?

117

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

semaphore deadlocks

118

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

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

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

ThreadMXBean does not show this as a deadlock!

121

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

JVM does not detect this deadlock

122

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

JVM does not detect this deadlock

122

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

Avoiding and diagnosing deadlocksAvoiding Liveness Hazards

123

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

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

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

Use open calls whenever possible

126

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

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); } } }}

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

We can force the context switch

129

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

simply add a sleep after first lock

130

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() {}}

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(); } }}

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

Won't this cause problems in production?

133

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

In production we only use Bank

134

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

HotSpot will optimize away empty sleepAWhileForTesting()

135

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

it is thus a zero cost

136

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

as long as SlowBank is never used

137

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

How can you verify the lock-ordering deadlock?

138

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

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

139

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

but that won't be a good unit test

140

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

Better via Java's ThreadMXBean

141

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

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

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; }

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"); }

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); }}

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)

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

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

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

However, if tryLock() fails it may be

150

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

a deadlock

151

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

or some thread taking a long time

152

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

or a thread in an infinite loop

153

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

But ThreadMXBean shows it as deadlocked

154

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

even if it is a temporary condition

155

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

The JVM has support for tryLock with synchronized

156

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

but it is hidden away

157

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

So here it is

158

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

159

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

Told you it was hidden!

160

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

It is hidden for a good reason

161

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

if you need tryLock functionality

162

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

rather use explicit locks (ReentrantLock)

163

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

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

Deadlock analysis with thread dumps

165

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

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

Can a deadlock be resolved?

167

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

NO with synchronized

168

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

YES with ReentrantLock

169

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

synchronized() goes into BLOCKED state

170

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

ReentrantLock.lock() goes into WAITING state

171

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

We can write a DealockArbitrator

172

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

This stops one of the threads with a DeadlockVictimError

173

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; }}

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; }

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; }}

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

177

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

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 heinz@javaspecialists.eu && olivier.croisier@zenika.com

179