I’m debugging a Java application that runs several threads. After a while of watching the log it seems that one of those threads is not running anymore. My guess is that the thread is waiting for a lock that is never released (the last output is before calling a synchronized method).
Can I configure a timeout to the thread; a sort of “wait for this lock but if it not available after 10 seconds don’t wait anymore!”
Deadlock occurs when multiple threads need the same locks but obtain them in different order. A Java multithreaded program may suffer from the deadlock condition because the synchronized keyword causes the executing thread to block while waiting for the lock, or monitor, associated with the specified object.
If you have two independent attribute in a class shared by multiple threads, you must synchronized the access to each variable, but there is no problem if one thread is accessing one of the attribute and another thread accessing the other at the same time. Synchronize does not prevent deadlock.
For example, instead of using synchronized ArrayList use the ConcurrentLinkedQueue. Avoid Nested Locks: Another way to avoid deadlock is to avoid giving a lock to multiple threads if we have already provided a lock to one thread. Since we must avoid allocating a lock to multiple threads. Using Thread.
As Michael Borgwardt points out, wait/notify is all about communication between threads, so you'll always end up with a race condition similar to the one described above. This is why the "only wait inside synchronized" rule is enforced.
You can use a java.util.concurrent.Lock instead of the intrinsic Object
locks. RentrantLock without fair ordering has the same basic behaviour and semantics as an intrinsic lock. There is a method tryLock
that takes a timeout parameter:
Lock lock = ...;
if (lock.tryLock(10L, TimeUnit.SECONDS)) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
Rather than adding extra code for debugging, you could use a debugging tool or profiler.
One option is to use something like JConsole (comes with the JDK) which includes a button called "Detect Deadlock" (at least it does in Java 6, I don't think it works in Java 5). Another option is to generate a thread dump to the console - on Unix you can type "kill -3 " while on Windows CTRL+BRK will work. Other profiling tools such as VisualVM (also in the JDK) can help. Finally there is JCarder which is "an open source tool for finding potential deadlocks in concurrent multi-threaded Java programs".
You can have the threads share an explicit lock (see java.util.concurrent.lock.Lock). You can then use Lock.tryLock(), which can take an optional timeout.
You can also use the jstack utility that comes with java 1.6 (not sure about 1.5) which will print out the state of all of your threads and what they may or may not be waiting for. Just call it with the process id. eg. :
> jstack PID
"Signal Dispatcher" daemon prio=10 tid=0x00000000408e8400 nid=0x79a8 runnable [0x0000000000000000..0x000000004143f810]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x00000000408c9400 nid=0x79a7 in Object.wait() [0x0000000041a7b000..0x0000000041a7bb00]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
- locked <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x00000000408c2000 nid=0x79a6 in Object.wait() [0x000000004197a000..0x000000004197ac80]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With