deadlock victim
DESCRIPTION
Support de la présentation "Deadlock Victim" à Devoxx-fr 2012, par Heinz Kabutz (javaspecialists.eu) et Olivier Croisier (zenika.com, thecodersbreakfast.net).TRANSCRIPT
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
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 [email protected] && [email protected]
179