Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2140045 | 5.0u10 | Xueming Shen | P4 | Resolved | Fixed | b01 |
Name: nt126004 Date: 09/09/2002
FULL PRODUCT VERSION :
java version "1.4.1-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b19)
Java HotSpot(TM) Client VM (build 1.4.1-rc-b19, mixed mode)
FULL OPERATING SYSTEM VERSION :
SunOs sss1 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-80
A DESCRIPTION OF THE PROBLEM :
Closing a SelectableChannel in one thread and calling
Selector.select() in another thread may result in a
deadlock situation (the channel being registred with the
selector). The reason is both SelectableChannel.close() and
Selector.select() synchronize on the same couple of objects
but in a different order as the following stack trace shows:
CLOSE (Thread A):
=================
java.nio.channels.spi.AbstractSelector.cancel() => enter
monitor for a java.util.HashSet (protecting this selector's
cancelled key list)
java.nio.channels.spi.AbstractSelectionKey.cancel()
java.nio.channels.spi.AbstractSelectableChannel.implCloseCha
nnel() => enter monitor for a java.lang.Object (protecting
this channel's keys)
java.nio.channels.spi.AbstractInterruptibleChannel.close()
SELECT (Thread B):
==================
java.nio.channels.spi.AbstractSelectableChannel.removeKey
() => enter monitor for a java.lang.Object (protecting
this channel's keys)
java.nio.channels.spi.AbstractSelector.deregister()
sun.nio.ch.DevPollSelectorImpl.implDereg()
sun.nio.ch.SelectorImpl.processDeregisterQueue() => enter
monitor for a java.util.HashSet (protecting this selector's
cancelled key list)
sun.nio.ch.DevPollSelectorImpl.doSelect()
sun.nio.ch.SelectorImpl.select()
It is possible that Thread A acquires a lock on the Object
then Thread B acquires a lock on the HashSet before Thread
A. This results in a deadlock.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example code under a Thread Analyser (e.g.
OptimizeIt).
Note: deadlock is unreproductible but thread / source code
analysis shows it can happen.
REPRODUCIBILITY :
This bug can be reproduced rarely.
---------- BEGIN SOURCE ----------
import java.nio.channels.*;
public class Deadlock
{
public static void main(String[] args) throws Exception
{
final Selector selector = Selector.open();
Thread thread = new Thread(new Runnable() {
public void run()
{
while (true)
{
try
{
System.out.println("select");
selector.select(100);
}
catch (Exception e)
{}
}
}
});
thread.start();
while (true)
{
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector, 0, null);
System.out.println("close");
channel.close();
}
}
}
---------- END SOURCE ----------
(Review ID: 164121)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.1-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b19)
Java HotSpot(TM) Client VM (build 1.4.1-rc-b19, mixed mode)
FULL OPERATING SYSTEM VERSION :
SunOs sss1 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-80
A DESCRIPTION OF THE PROBLEM :
Closing a SelectableChannel in one thread and calling
Selector.select() in another thread may result in a
deadlock situation (the channel being registred with the
selector). The reason is both SelectableChannel.close() and
Selector.select() synchronize on the same couple of objects
but in a different order as the following stack trace shows:
CLOSE (Thread A):
=================
java.nio.channels.spi.AbstractSelector.cancel() => enter
monitor for a java.util.HashSet (protecting this selector's
cancelled key list)
java.nio.channels.spi.AbstractSelectionKey.cancel()
java.nio.channels.spi.AbstractSelectableChannel.implCloseCha
nnel() => enter monitor for a java.lang.Object (protecting
this channel's keys)
java.nio.channels.spi.AbstractInterruptibleChannel.close()
SELECT (Thread B):
==================
java.nio.channels.spi.AbstractSelectableChannel.removeKey
() => enter monitor for a java.lang.Object (protecting
this channel's keys)
java.nio.channels.spi.AbstractSelector.deregister()
sun.nio.ch.DevPollSelectorImpl.implDereg()
sun.nio.ch.SelectorImpl.processDeregisterQueue() => enter
monitor for a java.util.HashSet (protecting this selector's
cancelled key list)
sun.nio.ch.DevPollSelectorImpl.doSelect()
sun.nio.ch.SelectorImpl.select()
It is possible that Thread A acquires a lock on the Object
then Thread B acquires a lock on the HashSet before Thread
A. This results in a deadlock.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example code under a Thread Analyser (e.g.
OptimizeIt).
Note: deadlock is unreproductible but thread / source code
analysis shows it can happen.
REPRODUCIBILITY :
This bug can be reproduced rarely.
---------- BEGIN SOURCE ----------
import java.nio.channels.*;
public class Deadlock
{
public static void main(String[] args) throws Exception
{
final Selector selector = Selector.open();
Thread thread = new Thread(new Runnable() {
public void run()
{
while (true)
{
try
{
System.out.println("select");
selector.select(100);
}
catch (Exception e)
{}
}
}
});
thread.start();
while (true)
{
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.register(selector, 0, null);
System.out.println("close");
channel.close();
}
}
}
---------- END SOURCE ----------
(Review ID: 164121)
======================================================================
- backported by
-
JDK-2140045 (se) Potential deadlock between Selector and SelectableChannel
-
- Resolved
-