-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
7, 8u60, 9
-
x86
-
windows_2012
FULL PRODUCT VERSION :
Both 1.7 and 1.8 JREs
ADDITIONAL OS VERSION INFORMATION :
Both Linux and Windows
A DESCRIPTION OF THE PROBLEM :
When we attempt to interrupt a thread sending data on a DatagramChannel, we sometimes encounter a deadlock between the thread doing the interrupt and the thread sending the data. We've determined that the locks in question are java.lang.Thread's blockerLock and sun.nio.ch.DatagramChannelImpl's stateLock.
I've included a test program which can reproduce it. ~40% of the time it happens on the first iteration, otherwise it could take some time.
REPRODUCIBILITY :
This bug can be reproduced occasionally.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DeadlockTest
{
private static final Logger LOG = LoggerFactory.getLogger(DeadlockTest.class);
private DatagramChannel receiver;
private InetSocketAddress target = new InetSocketAddress("localhost", 42421);
private boolean running = true;
private class Sender implements Runnable
{
private Thread thisThread = null;
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
thisThread = Thread.currentThread();
while (running)
{
try
{
DatagramChannel sender = DatagramChannel.open();
sender.setOption(StandardSocketOptions.SO_REUSEADDR, true);
sender.connect(target);
LOG.info("Sending");
sender.send(ByteBuffer.allocate(100).putInt(1), target);
// Sooner or later you stop seeing this message
LOG.info("Sent");
Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
}
catch (Exception e)
{
// Do Nothing
}
finally
{
if (Thread.interrupted())
{
LOG.info("Was interrupted");
}
}
}
}
public void interruptThis()
{
if (thisThread != null)
{
thisThread.interrupt();
}
}
}
@Test
public void testDeadlock() throws IOException, InterruptedException
{
receiver = DatagramChannel.open();
receiver.setOption(StandardSocketOptions.SO_REUSEADDR, true);
receiver.bind(new InetSocketAddress(42421));
ExecutorService executor = Executors.newSingleThreadExecutor();
Sender senderActor = new Sender();
executor.submit(senderActor);
while (running)
{
LOG.info("Before interrupt");
senderActor.interruptThis();
// Sooner or later, you stop seeing this message.
LOG.info("After interrupt");
Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
}
}
}
---------- END SOURCE ----------
Both 1.7 and 1.8 JREs
ADDITIONAL OS VERSION INFORMATION :
Both Linux and Windows
A DESCRIPTION OF THE PROBLEM :
When we attempt to interrupt a thread sending data on a DatagramChannel, we sometimes encounter a deadlock between the thread doing the interrupt and the thread sending the data. We've determined that the locks in question are java.lang.Thread's blockerLock and sun.nio.ch.DatagramChannelImpl's stateLock.
I've included a test program which can reproduce it. ~40% of the time it happens on the first iteration, otherwise it could take some time.
REPRODUCIBILITY :
This bug can be reproduced occasionally.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DeadlockTest
{
private static final Logger LOG = LoggerFactory.getLogger(DeadlockTest.class);
private DatagramChannel receiver;
private InetSocketAddress target = new InetSocketAddress("localhost", 42421);
private boolean running = true;
private class Sender implements Runnable
{
private Thread thisThread = null;
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
thisThread = Thread.currentThread();
while (running)
{
try
{
DatagramChannel sender = DatagramChannel.open();
sender.setOption(StandardSocketOptions.SO_REUSEADDR, true);
sender.connect(target);
LOG.info("Sending");
sender.send(ByteBuffer.allocate(100).putInt(1), target);
// Sooner or later you stop seeing this message
LOG.info("Sent");
Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
}
catch (Exception e)
{
// Do Nothing
}
finally
{
if (Thread.interrupted())
{
LOG.info("Was interrupted");
}
}
}
}
public void interruptThis()
{
if (thisThread != null)
{
thisThread.interrupt();
}
}
}
@Test
public void testDeadlock() throws IOException, InterruptedException
{
receiver = DatagramChannel.open();
receiver.setOption(StandardSocketOptions.SO_REUSEADDR, true);
receiver.bind(new InetSocketAddress(42421));
ExecutorService executor = Executors.newSingleThreadExecutor();
Sender senderActor = new Sender();
executor.submit(senderActor);
while (running)
{
LOG.info("Before interrupt");
senderActor.interruptThis();
// Sooner or later, you stop seeing this message.
LOG.info("After interrupt");
Thread.sleep(ThreadLocalRandom.current().nextLong(0, 100));
}
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8054039 Deadlock during interrupting FileChannel
-
- Closed
-
-
JDK-8198754 (ch) Separate blocking and non-blocking code paths (part 2)
-
- Resolved
-