Prefer JDK ThreadLocalRandom implementation over ours.

Motivation:

We have our own ThreadLocalRandom implementation to support older JDKs . That said we should prefer the JDK provided when running on JDK >= 7

Modification:

Using ThreadLocalRandom implementation of the JDK when possible.

Result:

Make use of JDK implementations when possible.
This commit is contained in:
Norman Maurer 2017-02-15 08:12:40 +01:00
parent 6a2dd3ea42
commit da94a908ad
16 changed files with 67 additions and 43 deletions

View File

@ -17,9 +17,8 @@ package io.netty.buffer;
import io.netty.util.CharsetUtil;
import io.netty.util.IllegalReferenceCountException;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@ -34,7 +33,6 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
@ -1813,7 +1811,7 @@ public abstract class AbstractByteBufTest {
assertEquals(1, buf.remaining());
byte[] data = new byte[a];
ThreadLocalRandom.current().nextBytes(data);
PlatformDependent.threadLocalRandom().nextBytes(data);
buffer.writeBytes(data);
buf = buffer.internalNioBuffer(0, a);

View File

@ -15,12 +15,12 @@
*/
package io.netty.buffer;
import io.netty.util.internal.PlatformDependent;
import org.junit.Assume;
import org.junit.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -30,14 +30,13 @@ import static org.junit.Assert.assertTrue;
* Tests sliced channel buffers
*/
public class SlicedByteBufTest extends AbstractByteBufTest {
private final Random random = new Random();
@Override
protected ByteBuf newBuffer(int length, int maxCapacity) {
Assume.assumeTrue(maxCapacity == Integer.MAX_VALUE);
ByteBuf buffer = Unpooled.wrappedBuffer(
new byte[length * 2], random.nextInt(length - 1) + 1, length);
new byte[length * 2], length > 1 ?
PlatformDependent.threadLocalRandom().nextInt(length - 1) + 1 : 0, length);
assertEquals(0, buffer.readerIndex());
assertEquals(length, buffer.writerIndex());
return buffer;
}

View File

@ -29,7 +29,7 @@ import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.stream.ChunkedInput;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import java.io.File;
import java.io.IOException;
@ -276,7 +276,7 @@ public class HttpPostRequestEncoder implements ChunkedInput<HttpContent> {
*/
private static String getNewMultipartDelimiter() {
// construct a generated delimiter
return Long.toHexString(ThreadLocalRandom.current().nextLong()).toLowerCase();
return Long.toHexString(PlatformDependent.threadLocalRandom().nextLong()).toLowerCase();
}
/**

View File

@ -29,7 +29,7 @@ import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.net.URI;
@ -102,7 +102,7 @@ public abstract class WebSocketClientHandshakerTest {
};
byte[] data = new byte[24];
ThreadLocalRandom.current().nextBytes(data);
PlatformDependent.threadLocalRandom().nextBytes(data);
// Create a EmbeddedChannel which we will use to encode a BinaryWebsocketFrame to bytes and so use these
// to test the actual handshaker.

View File

@ -20,8 +20,7 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.util.List;
@ -217,7 +216,7 @@ public class ByteToMessageDecoderTest {
}
});
byte[] bytes = new byte[1024];
ThreadLocalRandom.current().nextBytes(bytes);
PlatformDependent.threadLocalRandom().nextBytes(bytes);
assertTrue(channel.writeInbound(Unpooled.wrappedBuffer(bytes)));
assertBuffer(Unpooled.wrappedBuffer(bytes), (ByteBuf) channel.readInbound());
@ -249,7 +248,7 @@ public class ByteToMessageDecoderTest {
}
});
byte[] bytes = new byte[1024];
ThreadLocalRandom.current().nextBytes(bytes);
PlatformDependent.threadLocalRandom().nextBytes(bytes);
assertTrue(channel.writeInbound(Unpooled.wrappedBuffer(bytes)));
assertBuffer(Unpooled.wrappedBuffer(bytes, 0, bytes.length - 1), (ByteBuf) channel.readInbound());

View File

@ -22,12 +22,13 @@ import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
@ -82,7 +83,7 @@ public abstract class ZlibTest {
"</body></html>").getBytes(CharsetUtil.UTF_8);
static {
ThreadLocalRandom rand = ThreadLocalRandom.current();
Random rand = PlatformDependent.threadLocalRandom();
rand.nextBytes(BYTES_SMALL);
rand.nextBytes(BYTES_LARGE);
}

View File

@ -18,7 +18,6 @@ package io.netty.util;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -27,7 +26,6 @@ import java.lang.ref.ReferenceQueue;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static io.netty.util.internal.StringUtil.EMPTY_STRING;
import static io.netty.util.internal.StringUtil.NEWLINE;
@ -246,7 +244,7 @@ public class ResourceLeakDetector<T> {
}
if (level.ordinal() < Level.PARANOID.ordinal()) {
if ((ThreadLocalRandom.current().nextInt(0, samplingInterval)) == 0) {
if ((PlatformDependent.threadLocalRandom().nextInt(samplingInterval)) == 0) {
reportLeak(level);
return new DefaultResourceLeak(obj);
} else {

View File

@ -44,6 +44,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentMap;
@ -102,10 +103,26 @@ public final class PlatformDependent {
private static final boolean USE_DIRECT_BUFFER_NO_CLEANER;
private static final AtomicLong DIRECT_MEMORY_COUNTER;
private static final long DIRECT_MEMORY_LIMIT;
private static final ThreadLocalRandomProvider RANDOM_PROVIDER;
public static final boolean BIG_ENDIAN_NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
static {
if (javaVersion() >= 7) {
RANDOM_PROVIDER = new ThreadLocalRandomProvider() {
@Override
public Random current() {
return java.util.concurrent.ThreadLocalRandom.current();
}
};
} else {
RANDOM_PROVIDER = new ThreadLocalRandomProvider() {
@Override
public Random current() {
return ThreadLocalRandom.current();
}
};
}
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.noPreferDirect: {}", !DIRECT_BUFFER_PREFERRED);
}
@ -627,6 +644,13 @@ public final class PlatformDependent {
}
}
/**
* Return a {@link Random} which is not-threadsafe and so can only be used from the same thread.
*/
public static Random threadLocalRandom() {
return RANDOM_PROVIDER.current();
}
private static boolean isAndroid0() {
boolean android;
try {
@ -1086,6 +1110,10 @@ public final class PlatformDependent {
}
}
private interface ThreadLocalRandomProvider {
Random current();
}
private PlatformDependent() {
// only static method supported
}

View File

@ -16,13 +16,14 @@
package io.netty.handler.ssl.util;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import java.security.SecureRandom;
import java.util.Random;
/**
* Insecure {@link java.security.SecureRandom} which relies on {@link ThreadLocalRandom} for random number generation.
* Insecure {@link SecureRandom} which relies on {@link PlatformDependent#threadLocalRandom()} for random number
* generation.
*/
final class ThreadLocalInsecureRandom extends SecureRandom {
@ -95,6 +96,6 @@ final class ThreadLocalInsecureRandom extends SecureRandom {
}
private static Random random() {
return ThreadLocalRandom.current();
return PlatformDependent.threadLocalRandom();
}
}

View File

@ -21,7 +21,7 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBeh
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
@ -142,7 +142,7 @@ public class OpenSslEngineTest extends SSLEngineTest {
ByteBuffer src = allocateBuffer(1024 * 10);
byte[] data = new byte[src.capacity()];
ThreadLocalRandom.current().nextBytes(data);
PlatformDependent.threadLocalRandom().nextBytes(data);
src.put(data).flip();
ByteBuffer dst = allocateBuffer(1);
// Try to wrap multiple times so we are more likely to hit the issue.

View File

@ -41,7 +41,7 @@ import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.Promise;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -223,7 +223,7 @@ public abstract class SSLEngineTest {
case Heap:
return ByteBuffer.allocate(len);
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len);
default:
throw new Error();
@ -248,7 +248,7 @@ public abstract class SSLEngineTest {
case Heap:
return allocator.heapBuffer();
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
allocator.directBuffer() : allocator.heapBuffer();
default:
throw new Error();
@ -263,7 +263,7 @@ public abstract class SSLEngineTest {
case Heap:
return allocator.heapBuffer(initialCapacity);
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
allocator.directBuffer(initialCapacity) : allocator.heapBuffer(initialCapacity);
default:
throw new Error();
@ -278,7 +278,7 @@ public abstract class SSLEngineTest {
case Heap:
return allocator.heapBuffer(initialCapacity, maxCapacity);
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
allocator.directBuffer(initialCapacity, maxCapacity) :
allocator.heapBuffer(initialCapacity, maxCapacity);
default:
@ -339,7 +339,7 @@ public abstract class SSLEngineTest {
case Heap:
return allocator.compositeHeapBuffer();
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
allocator.compositeDirectBuffer() :
allocator.compositeHeapBuffer();
default:
@ -355,7 +355,7 @@ public abstract class SSLEngineTest {
case Heap:
return allocator.compositeHeapBuffer(maxNumComponents);
case Mixed:
return ThreadLocalRandom.current().nextBoolean() ?
return PlatformDependent.threadLocalRandom().nextBoolean() ?
allocator.compositeDirectBuffer(maxNumComponents) :
allocator.compositeHeapBuffer(maxNumComponents);
default:

View File

@ -649,6 +649,7 @@
<ignore>java.security.cert.CertPathValidatorException$BasicReason</ignore>
<ignore>java.util.concurrent.ConcurrentLinkedDeque</ignore>
<ignore>java.util.concurrent.ThreadLocalRandom</ignore>
<!-- JDK 9 -->
<ignore>java.nio.ByteBuffer</ignore>

View File

@ -26,7 +26,7 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.DefaultFileRegion;
import io.netty.channel.FileRegion;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.io.File;
@ -45,7 +45,7 @@ public class SocketFileRegionTest extends AbstractSocketTest {
static final byte[] data = new byte[1048576 * 10];
static {
ThreadLocalRandom.current().nextBytes(data);
PlatformDependent.threadLocalRandom().nextBytes(data);
}
@Test
@ -104,7 +104,7 @@ public class SocketFileRegionTest extends AbstractSocketTest {
file.deleteOnExit();
final FileOutputStream out = new FileOutputStream(file);
final Random random = ThreadLocalRandom.current();
final Random random = PlatformDependent.threadLocalRandom();
// Prepend random data which will not be transferred, so that we can test non-zero start offset
final int startOffset = random.nextInt(8192);

View File

@ -18,8 +18,8 @@ package io.netty.test.udt.util;
import com.barchart.udt.SocketUDT;
import com.barchart.udt.StatusUDT;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SocketUtils;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -222,7 +222,7 @@ public final class UnitHelp {
public static int[] randomIntArray(final int length, final int range) {
final int[] array = new int[length];
final Random generator = ThreadLocalRandom.current();
final Random generator = PlatformDependent.threadLocalRandom();
for (int i = 0; i < array.length; i++) {
array[i] = generator.nextInt(range);
}

View File

@ -19,7 +19,6 @@ import io.netty.buffer.ByteBufAllocator;
import io.netty.util.DefaultAttributeMap;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.ThrowableUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
@ -54,7 +53,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
new NotYetConnectedException(), AbstractUnsafe.class, "flush0()");
private final Channel parent;
private final long hashCode = ThreadLocalRandom.current().nextLong();
private final long hashCode = PlatformDependent.threadLocalRandom().nextLong();
private final Unsafe unsafe;
private final DefaultChannelPipeline pipeline;
private final ChannelFuture succeededFuture = new SucceededChannelFuture(this, null);

View File

@ -34,7 +34,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;
import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.PlatformDependent;
import org.junit.Test;
import java.io.DataInput;
@ -170,7 +170,7 @@ public class NioSocketChannelTest {
// Just some random bytes
byte[] bytes = new byte[1024];
ThreadLocalRandom.current().nextBytes(bytes);
PlatformDependent.threadLocalRandom().nextBytes(bytes);
Channel sc = null;
Channel cc = null;