This commit is contained in:
Lana Steuck 2015-11-30 13:27:19 -08:00
commit e528753f4d
182 changed files with 3819 additions and 1872 deletions

View File

@ -58,13 +58,13 @@ UNICODEDATA := $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt
# output
BASE_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/java.base/sun/text/resources
SL_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources
LD_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources
BIFILES := $(BASE_DATA_PKG_DIR)/CharacterBreakIteratorData \
$(BASE_DATA_PKG_DIR)/WordBreakIteratorData \
$(BASE_DATA_PKG_DIR)/LineBreakIteratorData \
$(BASE_DATA_PKG_DIR)/SentenceBreakIteratorData
BIFILES_TH := $(SA_DATA_PKG_DIR)/th/WordBreakIteratorData_th \
$(SA_DATA_PKG_DIR)/th/LineBreakIteratorData_th
BIFILES_TH := $(LD_DATA_PKG_DIR)/th/WordBreakIteratorData_th \
$(LD_DATA_PKG_DIR)/th/LineBreakIteratorData_th
$(BIFILES): $(BASE_DATA_PKG_DIR)/_the.bifiles
$(BASE_DATA_PKG_DIR)/_the.bifiles: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
@ -77,9 +77,9 @@ $(BASE_DATA_PKG_DIR)/_the.bifiles: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKIT
-spec $(UNICODEDATA)
$(TOUCH) $@
$(BIFILES_TH): $(SL_DATA_PKG_DIR)/_the.bifiles_th
$(SL_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
$(SL_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR)
$(BIFILES_TH): $(LD_DATA_PKG_DIR)/_the.bifiles_th
$(LD_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
$(LD_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR)
$(ECHO) $(LOG_INFO) "Generating BreakIteratorData_th"
$(MKDIR) -p $(@D)/th
$(RM) $(BIFILES_TH)

View File

@ -0,0 +1,55 @@
#
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
include GensrcCommon.gmk
################################################################################
define merge-providers
$(MKDIR) -p $(@D)
$(CAT) $^ > $@
endef
PROVIDER_FILE := META-INF/services/sun.jvmstat.monitor.MonitoredHostService
# Merge the local and remote sevice providers into jdk.jvmstat/META-INF/services
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE): \
$(JDK_TOPDIR)/src/jdk.jvmstat/share/classes/$(PROVIDER_FILE) \
$(JDK_TOPDIR)/src/jdk.jvmstat.rmi/share/classes/$(PROVIDER_FILE)
$(merge-providers)
# Copy the same service file into jdk.jvmstat.rmi so that they are kept the same.
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE): \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE)
$(install-file)
################################################################################
jdk.jvmstat: $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE)
all: jdk.jvmstat
.PHONY: all

View File

@ -33,4 +33,3 @@ include TextFileProcessing.gmk
include SetupJavaCompilers.gmk
# We need the tools.
include Tools.gmk

View File

@ -100,7 +100,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
SRC := $(GENSRC_UC_SRC), \
INCLUDE_FILES := $(GENSRC_UC_SRC_FILE), \
TOOLCHAIN := TOOLCHAIN_BUILD, \
CFLAGS := $(filter -D%, $(CFLAGS_JDKEXE)), \
OBJECT_DIR := $(GENSRC_UC_BIN), \
OUTPUT_DIR := $(GENSRC_UC_BIN), \
PROGRAM := genUnixConstants))

View File

@ -75,7 +75,7 @@ define SetupCompilePropertiesBody
# Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
# to .../support/gensrc/<module>/com/sun/tools/javac/resources/javac_zh_CN.java
# Strip away prefix and suffix, leaving for example only:
# Strip away prefix and suffix, leaving for example only:
# "<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN"
$1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \
$(SUPPORT_OUTPUTDIR)/gensrc/%, \

View File

@ -30,7 +30,6 @@ $(eval $(call SetupBuildLauncher, jinfo, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))
@ -39,7 +38,6 @@ $(eval $(call SetupBuildLauncher, jmap, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))
@ -52,7 +50,6 @@ $(eval $(call SetupBuildLauncher, jstack, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))

View File

@ -28,7 +28,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jconsole, \
MAIN_CLASS := sun.tools.jconsole.JConsole, \
JAVA_ARGS := -Djconsole.showOutputViewer, \
APP_CLASSPATH := /lib/jconsole.jar /lib/tools.jar /classes, \
CFLAGS_windows := -DJAVAW, \
LIBS_windows := user32.lib, \
))

View File

@ -27,5 +27,4 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jdb, \
MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \
APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
))

View File

@ -64,7 +64,6 @@ JAVA_MANIFEST := $(JDK_TOPDIR)/src/java.base/windows/native/launcher/java.manife
# Remaining parameters are named arguments. These include:
# MAIN_CLASS The Java main class to launch
# JAVA_ARGS Processed into a -DJAVA_ARGS C flag
# APP_CLASSPATH Processed into a -DAPP_CLASSPATH C flag
# CFLAGS Additional CFLAGS
# CFLAGS_windows Additional CFLAGS_windows
# LIBS_unix Additional LIBS_unix
@ -103,15 +102,6 @@ define SetupBuildLauncherBody
$1_CFLAGS += -DJAVA_ARGS=$$($1_JAVA_ARGS_STR)
endif
ifneq ($$($1_APP_CLASSPATH), )
$1_APP_CLASSPATH_STR := '{ $$(strip $$(foreach a, \
$$($1_APP_CLASSPATH), "$$a"$(COMMA) )) }'
# Remove the trailing comma
$1_APP_CLASSPATH_STR := $$(strip $$(subst $$(COMMA) }', }', \
$$($1_APP_CLASSPATH_STR)))
$1_CFLAGS += -DAPP_CLASSPATH=$$($1_APP_CLASSPATH_STR)
endif
$1_LIBS :=
ifeq ($(OPENJDK_TARGET_OS), macosx)
ifeq ($$($1_MACOSX_SIGNED), true)

View File

@ -43,7 +43,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS := $(LIBDL), \
LIBS_solaris := -lc, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2ucrypto, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA)

View File

@ -9,6 +9,7 @@ jdk.crypto.ec
jdk.crypto.mscapi
jdk.crypto.pkcs11
jdk.crypto.ucrypto
jdk.dynalink
jdk.localedata
jdk.naming.dns
jdk.scripting.nashorn

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,6 @@
package sun.nio.ch;
import java.nio.channels.spi.SelectorProvider;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
/**
* Creates this platform's default SelectorProvider
@ -40,32 +38,10 @@ public class DefaultSelectorProvider {
*/
private DefaultSelectorProvider() { }
@SuppressWarnings("unchecked")
private static SelectorProvider createProvider(String cn) {
Class<SelectorProvider> c;
try {
c = (Class<SelectorProvider>)Class.forName(cn);
} catch (ClassNotFoundException x) {
throw new AssertionError(x);
}
try {
return c.newInstance();
} catch (IllegalAccessException | InstantiationException x) {
throw new AssertionError(x);
}
}
/**
* Returns the default SelectorProvider.
*/
public static SelectorProvider create() {
String osname = AccessController
.doPrivileged(new GetPropertyAction("os.name"));
if (osname.equals("SunOS"))
return createProvider("sun.nio.ch.DevPollSelectorProvider");
if (osname.equals("Linux"))
return createProvider("sun.nio.ch.EPollSelectorProvider");
return new sun.nio.ch.PollSelectorProvider();
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch;
import java.nio.channels.spi.SelectorProvider;
/**
* Creates this platform's default SelectorProvider
*/
public class DefaultSelectorProvider {
/**
* Prevent instantiation.
*/
private DefaultSelectorProvider() { }
/**
* Returns the default SelectorProvider.
*/
public static SelectorProvider create() {
return new sun.nio.ch.EPollSelectorProvider();
}
}

View File

@ -272,22 +272,6 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
// (Done collecting options from props.)
boolean isClassFile(String name) {
if (!name.endsWith(".class")) return false;
for (String prefix = name; ; ) {
if (passFiles.contains(prefix)) return false;
int chop = prefix.lastIndexOf('/');
if (chop < 0) break;
prefix = prefix.substring(0, chop);
}
return true;
}
boolean isMetaInfFile(String name) {
return name.startsWith("/" + Utils.METAINF) ||
name.startsWith(Utils.METAINF);
}
// Get a new package, based on the old one.
private void makeNextPackage() {
pkg.reset();
@ -332,6 +316,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
InFile(JarEntry je) {
this(null, je);
}
boolean isClassFile() {
if (!name.endsWith(".class")) {
return false;
}
for (String prefix = name;;) {
if (passFiles.contains(prefix)) {
return false;
}
int chop = prefix.lastIndexOf('/');
if (chop < 0) {
break;
}
prefix = prefix.substring(0, chop);
}
return true;
}
boolean isMetaInfFile() {
return name.startsWith("/" + Utils.METAINF)
|| name.startsWith(Utils.METAINF);
}
boolean mustProcess() {
return !isMetaInfFile() && isClassFile();
}
long getInputLength() {
long len = (je != null)? je.getSize(): f.length();
assert(len >= 0) : this+".len="+len;
@ -391,7 +398,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
Package.File file = null;
// (5078608) : discount the resource files in META-INF
// from segment computation.
long inflen = (isMetaInfFile(name))
long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength();
@ -406,7 +413,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
assert(je.isDirectory() == name.endsWith("/"));
if (isClassFile(name)) {
if (inFile.mustProcess()) {
file = readClass(name, bits.getInputStream());
}
if (file == null) {
@ -429,7 +436,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
for (InFile inFile : inFiles) {
String name = inFile.name;
// (5078608) : discount the resource files completely from segmenting
long inflen = (isMetaInfFile(name))
long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength() ;
if ((segmentSize += inflen) > segmentLimit) {
@ -447,7 +454,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
if (verbose > 1)
Utils.log.fine("Reading " + name);
Package.File file = null;
if (isClassFile(name)) {
if (inFile.mustProcess()) {
file = readClass(name, strm);
if (file == null) {
strm.close();

View File

@ -732,13 +732,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object.
*/
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
append("-2147483648");
return this;
}
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
int spaceNeeded = count + Integer.stringSize(i);
ensureCapacityInternal(spaceNeeded);
if (isLatin1()) {
Integer.getChars(i, spaceNeeded, value);
@ -764,13 +758,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return a reference to this object.
*/
public AbstractStringBuilder append(long l) {
if (l == Long.MIN_VALUE) {
append("-9223372036854775808");
return this;
}
int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
: Long.stringSize(l);
int spaceNeeded = count + appendedLength;
int spaceNeeded = count + Long.stringSize(l);
ensureCapacityInternal(spaceNeeded);
if (isLatin1()) {
Long.getChars(l, spaceNeeded, value);

View File

@ -396,7 +396,7 @@ public final class Integer extends Number implements Comparable<Integer> {
} while (charPos > offset);
}
static final char [] DigitTens = {
static final byte[] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
@ -409,7 +409,7 @@ public final class Integer extends Number implements Comparable<Integer> {
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
} ;
static final char [] DigitOnes = {
static final byte[] DigitOnes = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
@ -422,21 +422,6 @@ public final class Integer extends Number implements Comparable<Integer> {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
} ;
// I use the "invariant division by multiplication" trick to
// accelerate Integer.toString. In particular we want to
// avoid division by 10.
//
// The "trick" has roughly the same performance characteristics
// as the "classic" Integer.toString code on a non-JIT VM.
// The trick avoids .rem and .div calls but has a longer code
// path and is thus dominated by dispatch overhead. In the
// JIT case the dispatch overhead doesn't exist and the
// "trick" is considerably faster than the classic code.
//
// RE: Division by Invariant Integers using Multiplication
// T Gralund, P Montgomery
// ACM PLDI 1994
//
/**
* Returns a {@code String} object representing the
@ -450,9 +435,7 @@ public final class Integer extends Number implements Comparable<Integer> {
*/
@HotSpotIntrinsicCandidate
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
@ -489,84 +472,105 @@ public final class Integer extends Number implements Comparable<Integer> {
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Integer.MIN_VALUE
* @implNote This method converts positive inputs into negative
* values, to cover the Integer.MIN_VALUE case. Converting otherwise
* (negative to positive) will expose -Integer.MIN_VALUE that overflows
* integer.
*/
static void getChars(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
boolean negative = i < 0;
if (!negative) {
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
while (i <= -100) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
r = (q * 100) - i;
i = q;
buf [--charPos] = (byte)DigitOnes[r];
buf [--charPos] = (byte)DigitTens[r];
buf[--charPos] = DigitOnes[r];
buf[--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = (byte)digits [r];
i = q;
if (i == 0) break;
// We know there are at most two digits left at this point.
q = i / 10;
r = (q * 10) - i;
buf[--charPos] = (byte)('0' + r);
// Whatever left is the remaining digit.
if (q < 0) {
buf[--charPos] = (byte)('0' - q);
}
if (sign != 0) {
buf [--charPos] = (byte)sign;
if (negative) {
buf[--charPos] = (byte)'-';
}
}
static void getCharsUTF16(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
// Get 2 digits/iteration using ints
while (i <= -100) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
r = (q * 100) - i;
i = q;
StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, DigitTens[r]);
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
i = q;
if (i == 0) break;
// We know there are at most two digits left at this point.
q = i / 10;
r = (q * 10) - i;
StringUTF16.putChar(buf, --charPos, '0' + r);
// Whatever left is the remaining digit.
if (q < 0) {
StringUTF16.putChar(buf, --charPos, '0' - q);
}
if (sign != 0) {
StringUTF16.putChar(buf, --charPos, sign);
if (negative) {
StringUTF16.putChar(buf, --charPos, '-');
}
}
// Left here for compatibility reasons, see JDK-8143900.
static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
/**
* Returns the string representation size for a given int value.
*
* @param x int value
* @return string size
*
* @implNote There are other ways to compute this: e.g. binary search,
* but values are biased heavily towards zero, and therefore linear search
* wins. The iteration results are also routinely inlined in the generated
* code after loop unrolling.
*/
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
int d = 1;
if (x >= 0) {
d = 0;
x = -x;
}
int p = -10;
for (int i = 1; i < 10; i++) {
if (x > p)
return i + d;
p = 10 * p;
}
return 10 + d;
}
/**

View File

@ -448,9 +448,7 @@ public final class Long extends Number implements Comparable<Long> {
* @return a string representation of the argument in base&nbsp;10.
*/
public static String toString(long i) {
if (i == Long.MIN_VALUE)
return "-9223372036854775808";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
@ -481,58 +479,59 @@ public final class Long extends Number implements Comparable<Long> {
}
/**
* Places characters representing the integer i into the
* Places characters representing the long i into the
* character array buf. The characters are placed into
* the buffer backwards starting with the least significant
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Long.MIN_VALUE
* @implNote This method converts positive inputs into negative
* values, to cover the Long.MIN_VALUE case. Converting otherwise
* (negative to positive) will expose -Long.MIN_VALUE that overflows
* long.
*/
static void getChars(long i, int index, byte[] buf) {
long q;
int r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
// Get 2 digits/iteration using longs until quotient fits into an int
while (i > Integer.MAX_VALUE) {
while (i <= Integer.MIN_VALUE) {
q = i / 100;
// really: r = i - (q * 100);
r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
r = (int)((q * 100) - i);
i = q;
buf[--charPos] = (byte)Integer.DigitOnes[r];
buf[--charPos] = (byte)Integer.DigitTens[r];
buf[--charPos] = Integer.DigitOnes[r];
buf[--charPos] = Integer.DigitTens[r];
}
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
while (i2 >= 65536) {
while (i2 <= -100) {
q2 = i2 / 100;
// really: r = i2 - (q * 100);
r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
r = (q2 * 100) - i2;
i2 = q2;
buf[--charPos] = (byte)Integer.DigitOnes[r];
buf[--charPos] = (byte)Integer.DigitTens[r];
buf[--charPos] = Integer.DigitOnes[r];
buf[--charPos] = Integer.DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i2 <= 65536, i2);
for (;;) {
q2 = (i2 * 52429) >>> (16+3);
r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
buf[--charPos] = (byte)Integer.digits[r];
i2 = q2;
if (i2 == 0) break;
// We know there are at most two digits left at this point.
q2 = i2 / 10;
r = (q2 * 10) - i2;
buf[--charPos] = (byte)('0' + r);
// Whatever left is the remaining digit.
if (q2 < 0) {
buf[--charPos] = (byte)('0' - q2);
}
if (sign != 0) {
buf[--charPos] = (byte)sign;
if (negative) {
buf[--charPos] = (byte)'-';
}
}
@ -540,18 +539,16 @@ public final class Long extends Number implements Comparable<Long> {
long q;
int r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
// Get 2 digits/iteration using longs until quotient fits into an int
while (i > Integer.MAX_VALUE) {
while (i <= Integer.MIN_VALUE) {
q = i / 100;
// really: r = i - (q * 100);
r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
r = (int)((q * 100) - i);
i = q;
StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
@ -560,38 +557,53 @@ public final class Long extends Number implements Comparable<Long> {
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
while (i2 >= 65536) {
while (i2 <= -100) {
q2 = i2 / 100;
// really: r = i2 - (q * 100);
r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
r = (q2 * 100) - i2;
i2 = q2;
StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
}
// Fall thru to fast mode for smaller numbers
// assert(i2 <= 65536, i2);
for (;;) {
q2 = (i2 * 52429) >>> (16+3);
r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
i2 = q2;
if (i2 == 0) break;
// We know there are at most two digits left at this point.
q2 = i2 / 10;
r = (q2 * 10) - i2;
StringUTF16.putChar(buf, --charPos, '0' + r);
// Whatever left is the remaining digit.
if (q2 < 0) {
StringUTF16.putChar(buf, --charPos, '0' - q2);
}
if (sign != 0) {
StringUTF16.putChar(buf, --charPos, sign);
if (negative) {
StringUTF16.putChar(buf, --charPos, '-');
}
}
// Requires positive x
/**
* Returns the string representation size for a given long value.
*
* @param x long value
* @return string size
*
* @implNote There are other ways to compute this: e.g. binary search,
* but values are biased heavily towards zero, and therefore linear search
* wins. The iteration results are also routinely inlined in the generated
* code after loop unrolling.
*/
static int stringSize(long x) {
long p = 10;
for (int i=1; i<19; i++) {
if (x < p)
return i;
p = 10*p;
int d = 1;
if (x >= 0) {
d = 0;
x = -x;
}
return 19;
long p = -10;
for (int i = 1; i < 19; i++) {
if (x > p)
return i + d;
p = 10 * p;
}
return 19 + d;
}
/**

View File

@ -44,7 +44,7 @@ import sun.reflect.Reflection;
*/
public class Runtime {
private static Runtime currentRuntime = new Runtime();
private static final Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.

View File

@ -730,7 +730,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
count = fields.get("count", 0);
}
protected synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
super.getBytes(dst, dstBegin, coder);
}
}

View File

@ -938,7 +938,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
Class<?> arrayElement = arrayType.getComponentType();
MethodType mtype = type();
boolean match = true, fail = false;
for (int i = pos; i < arrayLength; i++) {
for (int i = pos; i < pos + arrayLength; i++) {
Class<?> ptype = mtype.parameterType(i);
if (ptype != arrayElement) {
match = false;

View File

@ -418,7 +418,7 @@ public abstract class DateFormat extends Format {
* index information as described above.
* @return A <code>Date</code> parsed from the string. In case of
* error, returns null.
* @exception NullPointerException if <code>pos</code> is null.
* @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);

View File

@ -225,7 +225,7 @@ public abstract class Format implements Serializable, Cloneable {
* index information as described above.
* @return An <code>Object</code> parsed from the string. In case of
* error, returns null.
* @exception NullPointerException if <code>pos</code> is null.
* @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public abstract Object parseObject (String source, ParsePosition pos);
@ -237,6 +237,7 @@ public abstract class Format implements Serializable, Cloneable {
* @return An <code>Object</code> parsed from the string.
* @exception ParseException if the beginning of the specified string
* cannot be parsed.
* @throws NullPointerException if {@code source} is null.
*/
public Object parseObject(String source) throws ParseException {
ParsePosition pos = new ParsePosition(0);

View File

@ -1068,7 +1068,7 @@ public class MessageFormat extends Format {
* index information as described above.
* @return An <code>Object</code> array parsed from the string. In case of
* error, returns null.
* @exception NullPointerException if <code>pos</code> is null.
* @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);

View File

@ -271,7 +271,7 @@ public abstract class NumberFormat extends Format {
* index information as described above.
* @return A <code>Number</code> parsed from the string. In case of
* error, returns null.
* @exception NullPointerException if <code>pos</code> is null.
* @throws NullPointerException if {@code source} or {@code pos} is null.
*/
@Override
public final Object parseObject(String source, ParsePosition pos) {

View File

@ -596,7 +596,16 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
/** Number of CPUS, to place bounds on some sizings */
static final int NCPU = Runtime.getRuntime().availableProcessors();
/** For serialization compatibility. */
/**
* Serialized pseudo-fields, provided only for jdk7 compatibility.
* @serialField segments Segment[]
* The segments, each of which is a specialized hash table.
* @serialField segmentMask int
* Mask value for indexing into segments. The upper bits of a
* key's hash code are used to choose the segment.
* @serialField segmentShift int
* Shift value for indexing within segments.
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("segments", Segment[].class),
new ObjectStreamField("segmentMask", Integer.TYPE),
@ -1382,8 +1391,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
* @param s the stream
* @throws java.io.IOException if an I/O error occurs
* @serialData
* the key (Object) and value (Object)
* for each key-value mapping, followed by a null pair.
* the serialized fields, followed by the key (Object) and value
* (Object) for each key-value mapping, followed by a null pair.
* The key-value mappings are emitted in no particular order.
*/
private void writeObject(java.io.ObjectOutputStream s)
@ -1419,7 +1428,6 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
s.writeObject(null);
s.writeObject(null);
segments = null; // throw away
}
/**

View File

@ -185,7 +185,7 @@ package java.util.concurrent;
* }
* }}</pre>
*
* As a further improvement, notice that the left task need not even exist.
* As a further optimization, notice that the left task need not even exist.
* Instead of creating a new one, we can iterate using the original task,
* and add a pending count for each fork. Additionally, because no task
* in this tree implements an {@link #onCompletion(CountedCompleter)} method,
@ -208,7 +208,7 @@ package java.util.concurrent;
* }
* }}</pre>
*
* Additional improvements of such classes might entail precomputing
* Additional optimizations of such classes might entail precomputing
* pending counts so that they can be established in constructors,
* specializing classes for leaf steps, subdividing by say, four,
* instead of two per iteration, and using an adaptive threshold
@ -260,9 +260,9 @@ package java.util.concurrent;
* }}</pre>
*
* In this example, as well as others in which tasks have no other
* effects except to compareAndSet a common result, the trailing
* unconditional invocation of {@code tryComplete} could be made
* conditional ({@code if (result.get() == null) tryComplete();})
* effects except to {@code compareAndSet} a common result, the
* trailing unconditional invocation of {@code tryComplete} could be
* made conditional ({@code if (result.get() == null) tryComplete();})
* because no further bookkeeping is required to manage completions
* once the root task completes.
*
@ -624,7 +624,7 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
* any one (versus all) of several subtask results are obtained.
* However, in the common (and recommended) case in which {@code
* setRawResult} is not overridden, this effect can be obtained
* more simply using {@code quietlyCompleteRoot();}.
* more simply using {@link #quietlyCompleteRoot()}.
*
* @param rawResult the raw result
*/
@ -639,9 +639,9 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
/**
* If this task's pending count is zero, returns this task;
* otherwise decrements its pending count and returns {@code
* null}. This method is designed to be used with {@link
* #nextComplete} in completion traversal loops.
* otherwise decrements its pending count and returns {@code null}.
* This method is designed to be used with {@link #nextComplete} in
* completion traversal loops.
*
* @return this task, if pending count was zero, else {@code null}
*/

View File

@ -703,7 +703,8 @@ public class ForkJoinPool extends AbstractExecutorService {
* Returns a new worker thread operating in the given pool.
*
* @param pool the pool this thread works in
* @return the new worker thread
* @return the new worker thread, or {@code null} if the request
* to create a thread is rejected
* @throws NullPointerException if the pool is null
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
@ -1053,7 +1054,7 @@ public class ForkJoinPool extends AbstractExecutorService {
}
/**
* Shared version of pop.
* Shared version of tryUnpush.
*/
final boolean trySharedUnpush(ForkJoinTask<?> task) {
boolean popped = false;
@ -1064,7 +1065,8 @@ public class ForkJoinPool extends AbstractExecutorService {
ForkJoinTask<?> t = (ForkJoinTask<?>) U.getObject(a, offset);
if (t == task &&
U.compareAndSwapInt(this, QLOCK, 0, 1)) {
if (U.compareAndSwapObject(a, offset, task, null)) {
if (top == s + 1 && array == a &&
U.compareAndSwapObject(a, offset, task, null)) {
popped = true;
top = s;
}
@ -1250,12 +1252,14 @@ public class ForkJoinPool extends AbstractExecutorService {
for (CountedCompleter<?> r = t;;) {
if (r == task) {
if ((mode & IS_OWNED) == 0) {
boolean popped;
boolean popped = false;
if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
if (popped =
if (top == s && array == a &&
U.compareAndSwapObject(a, offset,
t, null))
t, null)) {
popped = true;
top = s - 1;
}
U.putOrderedInt(this, QLOCK, 0);
if (popped)
return t;

View File

@ -132,11 +132,10 @@ public class ScheduledThreadPoolExecutor
/*
* This class specializes ThreadPoolExecutor implementation by
*
* 1. Using a custom task type, ScheduledFutureTask for
* tasks, even those that don't require scheduling (i.e.,
* those submitted using ExecutorService execute, not
* ScheduledExecutorService methods) which are treated as
* delayed tasks with a delay of zero.
* 1. Using a custom task type ScheduledFutureTask, even for tasks
* that don't require scheduling because they are submitted
* using ExecutorService rather than ScheduledExecutorService
* methods, which are treated as tasks with a delay of zero.
*
* 2. Using a custom queue (DelayedWorkQueue), a variant of
* unbounded DelayQueue. The lack of capacity constraint and
@ -177,24 +176,17 @@ public class ScheduledThreadPoolExecutor
*/
private static final AtomicLong sequencer = new AtomicLong();
/**
* Returns current nanosecond time.
*/
static final long now() {
return System.nanoTime();
}
private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {
/** Sequence number to break ties FIFO */
private final long sequenceNumber;
/** The time the task is enabled to execute in nanoTime units */
/** The nanoTime-based time when the task is enabled to execute. */
private volatile long time;
/**
* Period in nanoseconds for repeating tasks.
* Period for repeating tasks, in nanoseconds.
* A positive value indicates fixed-rate execution.
* A negative value indicates fixed-delay execution.
* A value of 0 indicates a non-repeating (one-shot) task.
@ -244,7 +236,7 @@ public class ScheduledThreadPoolExecutor
}
public long getDelay(TimeUnit unit) {
return unit.convert(time - now(), NANOSECONDS);
return unit.convert(time - System.nanoTime(), NANOSECONDS);
}
public int compareTo(Delayed other) {
@ -287,6 +279,9 @@ public class ScheduledThreadPoolExecutor
}
public boolean cancel(boolean mayInterruptIfRunning) {
// The racy read of heapIndex below is benign:
// if heapIndex < 0, then OOTA guarantees that we have surely
// been removed; else we recheck under lock in remove()
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
@ -528,7 +523,7 @@ public class ScheduledThreadPoolExecutor
* Returns the nanoTime-based trigger time of a delayed action.
*/
long triggerTime(long delay) {
return now() +
return System.nanoTime() +
((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}

View File

@ -365,12 +365,17 @@ public abstract class AtomicIntegerFieldUpdater<T> {
/**
* Standard hotspot implementation using intrinsics.
*/
private static class AtomicIntegerFieldUpdaterImpl<T>
extends AtomicIntegerFieldUpdater<T> {
private static final class AtomicIntegerFieldUpdaterImpl<T>
extends AtomicIntegerFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
/**
* if field is protected, the subclass constructing updater, else
* the same as tclass
*/
private final Class<?> cclass;
/** class holding the field */
private final Class<T> tclass;
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
@ -399,17 +404,15 @@ public abstract class AtomicIntegerFieldUpdater<T> {
throw new RuntimeException(ex);
}
Class<?> fieldt = field.getType();
if (fieldt != int.class)
if (field.getType() != int.class)
throw new IllegalArgumentException("Must be integer type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers) &&
caller != tclass) ? caller : null;
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
offset = U.objectFieldOffset(field);
this.offset = U.objectFieldOffset(field);
}
/**
@ -428,81 +431,87 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return false;
}
private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.
*/
private final void accessCheck(T obj) {
if (!cclass.isInstance(obj))
throwAccessCheckException(obj);
}
/**
* Throws access exception if accessCheck failed due to
* protected access, else ClassCastException.
*/
private final void throwAccessCheckException(T obj) {
if (cclass == tclass)
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
else
throw new RuntimeException(
new IllegalAccessException(
"Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()));
}
public boolean compareAndSet(T obj, int expect, int update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final boolean compareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, int expect, int update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final boolean weakCompareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
}
public void set(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final void set(T obj, int newValue) {
accessCheck(obj);
U.putIntVolatile(obj, offset, newValue);
}
public void lazySet(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final void lazySet(T obj, int newValue) {
accessCheck(obj);
U.putOrderedInt(obj, offset, newValue);
}
public final int get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
accessCheck(obj);
return U.getIntVolatile(obj, offset);
}
public int getAndSet(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final int getAndSet(T obj, int newValue) {
accessCheck(obj);
return U.getAndSetInt(obj, offset, newValue);
}
public int getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public int getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public int getAndAdd(T obj, int delta) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final int getAndAdd(T obj, int delta) {
accessCheck(obj);
return U.getAndAddInt(obj, offset, delta);
}
public int incrementAndGet(T obj) {
public final int getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public final int getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public final int incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
public int decrementAndGet(T obj) {
public final int decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
public int addAndGet(T obj, int delta) {
public final int addAndGet(T obj, int delta) {
return getAndAdd(obj, delta) + delta;
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
}
throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()
)
);
}
}
}

View File

@ -365,11 +365,16 @@ public abstract class AtomicLongFieldUpdater<T> {
return next;
}
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
/**
* if field is protected, the subclass constructing updater, else
* the same as tclass
*/
private final Class<?> cclass;
/** class holding the field */
private final Class<T> tclass;
CASUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@ -397,103 +402,110 @@ public abstract class AtomicLongFieldUpdater<T> {
throw new RuntimeException(ex);
}
Class<?> fieldt = field.getType();
if (fieldt != long.class)
if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers) &&
caller != tclass) ? caller : null;
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
offset = U.objectFieldOffset(field);
this.offset = U.objectFieldOffset(field);
}
private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.
*/
private final void accessCheck(T obj) {
if (!cclass.isInstance(obj))
throwAccessCheckException(obj);
}
/**
* Throws access exception if accessCheck failed due to
* protected access, else ClassCastException.
*/
private final void throwAccessCheckException(T obj) {
if (cclass == tclass)
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
else
throw new RuntimeException(
new IllegalAccessException(
"Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()));
}
public boolean compareAndSet(T obj, long expect, long update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, long expect, long update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final boolean weakCompareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
public void set(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final void set(T obj, long newValue) {
accessCheck(obj);
U.putLongVolatile(obj, offset, newValue);
}
public void lazySet(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final void lazySet(T obj, long newValue) {
accessCheck(obj);
U.putOrderedLong(obj, offset, newValue);
}
public long get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final long get(T obj) {
accessCheck(obj);
return U.getLongVolatile(obj, offset);
}
public long getAndSet(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final long getAndSet(T obj, long newValue) {
accessCheck(obj);
return U.getAndSetLong(obj, offset, newValue);
}
public long getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public long getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public long getAndAdd(T obj, long delta) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final long getAndAdd(T obj, long delta) {
accessCheck(obj);
return U.getAndAddLong(obj, offset, delta);
}
public long incrementAndGet(T obj) {
public final long getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public final long getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
public final long incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
public long decrementAndGet(T obj) {
public final long decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
public long addAndGet(T obj, long delta) {
public final long addAndGet(T obj, long delta) {
return getAndAdd(obj, delta) + delta;
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
}
throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()
)
);
}
}
private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
/**
* if field is protected, the subclass constructing updater, else
* the same as tclass
*/
private final Class<?> cclass;
/** class holding the field */
private final Class<T> tclass;
LockedUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@ -521,28 +533,46 @@ public abstract class AtomicLongFieldUpdater<T> {
throw new RuntimeException(ex);
}
Class<?> fieldt = field.getType();
if (fieldt != long.class)
if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers) &&
caller != tclass) ? caller : null;
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
offset = U.objectFieldOffset(field);
this.offset = U.objectFieldOffset(field);
}
private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.
*/
private final void accessCheck(T obj) {
if (!cclass.isInstance(obj))
throw accessCheckException(obj);
}
public boolean compareAndSet(T obj, long expect, long update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
/**
* Returns access exception if accessCheck failed due to
* protected access, else ClassCastException.
*/
private final RuntimeException accessCheckException(T obj) {
if (cclass == tclass)
return new ClassCastException();
else
return new RuntimeException(
new IllegalAccessException(
"Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()));
}
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
synchronized (this) {
long v = U.getLong(obj, offset);
if (v != expect)
@ -552,42 +582,27 @@ public abstract class AtomicLongFieldUpdater<T> {
}
}
public boolean weakCompareAndSet(T obj, long expect, long update) {
public final boolean weakCompareAndSet(T obj, long expect, long update) {
return compareAndSet(obj, expect, update);
}
public void set(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final void set(T obj, long newValue) {
accessCheck(obj);
synchronized (this) {
U.putLong(obj, offset, newValue);
}
}
public void lazySet(T obj, long newValue) {
public final void lazySet(T obj, long newValue) {
set(obj, newValue);
}
public long get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
public final long get(T obj) {
accessCheck(obj);
synchronized (this) {
return U.getLong(obj, offset);
}
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
}
throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()
)
);
}
}
/**

View File

@ -286,9 +286,15 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
extends AtomicReferenceFieldUpdater<T,V> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<V> vclass;
/**
* if field is protected, the subclass constructing updater, else
* the same as tclass
*/
private final Class<?> cclass;
/** class holding the field */
private final Class<T> tclass;
/** field value type */
private final Class<V> vclass;
/*
* Internal type checks within all update methods contain
@ -340,14 +346,10 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers) &&
caller != tclass) ? caller : null;
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
if (vclass == Object.class)
this.vclass = null;
else
this.vclass = vclass;
offset = U.objectFieldOffset(field);
this.vclass = vclass;
this.offset = U.objectFieldOffset(field);
}
/**
@ -366,83 +368,78 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
return false;
}
void targetCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.
*/
private final void accessCheck(T obj) {
if (!cclass.isInstance(obj))
throwAccessCheckException(obj);
}
void updateCheck(T obj, V update) {
if (!tclass.isInstance(obj) ||
(update != null && vclass != null && !vclass.isInstance(update)))
/**
* Throws access exception if accessCheck failed due to
* protected access, else ClassCastException.
*/
private final void throwAccessCheckException(T obj) {
if (cclass == tclass)
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
else
throw new RuntimeException(
new IllegalAccessException(
"Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()));
}
public boolean compareAndSet(T obj, V expect, V update) {
if (obj == null || obj.getClass() != tclass || cclass != null ||
(update != null && vclass != null &&
vclass != update.getClass()))
updateCheck(obj, update);
private final void valueCheck(V v) {
if (v != null && !(vclass.isInstance(v)))
throwCCE();
}
static void throwCCE() {
throw new ClassCastException();
}
public final boolean compareAndSet(T obj, V expect, V update) {
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, V expect, V update) {
public final boolean weakCompareAndSet(T obj, V expect, V update) {
// same implementation as strong form for now
if (obj == null || obj.getClass() != tclass || cclass != null ||
(update != null && vclass != null &&
vclass != update.getClass()))
updateCheck(obj, update);
accessCheck(obj);
valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
public void set(T obj, V newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null ||
(newValue != null && vclass != null &&
vclass != newValue.getClass()))
updateCheck(obj, newValue);
public final void set(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
U.putObjectVolatile(obj, offset, newValue);
}
public void lazySet(T obj, V newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null ||
(newValue != null && vclass != null &&
vclass != newValue.getClass()))
updateCheck(obj, newValue);
public final void lazySet(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
U.putOrderedObject(obj, offset, newValue);
}
@SuppressWarnings("unchecked")
public V get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null)
targetCheck(obj);
public final V get(T obj) {
accessCheck(obj);
return (V)U.getObjectVolatile(obj, offset);
}
@SuppressWarnings("unchecked")
public V getAndSet(T obj, V newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null ||
(newValue != null && vclass != null &&
vclass != newValue.getClass()))
updateCheck(obj, newValue);
public final V getAndSet(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
return (V)U.getAndSetObject(obj, offset, newValue);
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
}
throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()
)
);
}
}
}

View File

@ -922,7 +922,7 @@ public abstract class AbstractQueuedLongSynchronizer
/**
* Queries whether any threads have ever contended to acquire this
* synchronizer; that is if an acquire method has ever blocked.
* synchronizer; that is, if an acquire method has ever blocked.
*
* <p>In this implementation, this operation returns in
* constant time.
@ -977,13 +977,11 @@ public abstract class AbstractQueuedLongSynchronizer
* guaranteeing termination.
*/
Node t = tail;
Thread firstThread = null;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
for (Node p = tail; p != null && p != head; p = p.prev) {
Thread t = p.thread;
if (t != null)
firstThread = t;
}
return firstThread;
}
@ -1031,8 +1029,8 @@ public abstract class AbstractQueuedLongSynchronizer
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
* getFirstQueuedThread() != Thread.currentThread() &&
* hasQueuedThreads()}</pre>
* getFirstQueuedThread() != Thread.currentThread()
* && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@ -1635,7 +1633,7 @@ public abstract class AbstractQueuedLongSynchronizer
transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@ -1723,7 +1721,7 @@ public abstract class AbstractQueuedLongSynchronizer
timedout = transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@ -1847,8 +1845,9 @@ public abstract class AbstractQueuedLongSynchronizer
* Initializes head and tail fields on first contention.
*/
private final void initializeSyncQueue() {
if (U.compareAndSwapObject(this, HEAD, null, new Node()))
tail = head;
Node h;
if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
tail = h;
}
/**

View File

@ -1388,7 +1388,7 @@ public abstract class AbstractQueuedSynchronizer
/**
* Queries whether any threads have ever contended to acquire this
* synchronizer; that is if an acquire method has ever blocked.
* synchronizer; that is, if an acquire method has ever blocked.
*
* <p>In this implementation, this operation returns in
* constant time.
@ -1443,13 +1443,11 @@ public abstract class AbstractQueuedSynchronizer
* guaranteeing termination.
*/
Node t = tail;
Thread firstThread = null;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
for (Node p = tail; p != null && p != head; p = p.prev) {
Thread t = p.thread;
if (t != null)
firstThread = t;
}
return firstThread;
}
@ -1497,8 +1495,8 @@ public abstract class AbstractQueuedSynchronizer
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
* getFirstQueuedThread() != Thread.currentThread() &&
* hasQueuedThreads()}</pre>
* getFirstQueuedThread() != Thread.currentThread()
* && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@ -2099,7 +2097,7 @@ public abstract class AbstractQueuedSynchronizer
transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@ -2187,7 +2185,7 @@ public abstract class AbstractQueuedSynchronizer
timedout = transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@ -2311,8 +2309,9 @@ public abstract class AbstractQueuedSynchronizer
* Initializes head and tail fields on first contention.
*/
private final void initializeSyncQueue() {
if (U.compareAndSwapObject(this, HEAD, null, new Node()))
tail = head;
Node h;
if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
tail = h;
}
/**

View File

@ -81,12 +81,17 @@ package java.util.concurrent.locks;
* method is designed for use only in constructions of the form:
*
* <pre> {@code
* while (!canProceed()) { ... LockSupport.park(this); }}</pre>
* while (!canProceed()) {
* // ensure request to unpark is visible to other threads
* ...
* LockSupport.park(this);
* }}</pre>
*
* where neither {@code canProceed} nor any other actions prior to the
* call to {@code park} entail locking or blocking. Because only one
* permit is associated with each thread, any intermediary uses of
* {@code park} could interfere with its intended effects.
* where no actions by the thread publishing a request to unpark,
* prior to the call to {@code park}, entail locking or blocking.
* Because only one permit is associated with each thread, any
* intermediary uses of {@code park}, including implicitly via class
* loading, could lead to an unresponsive thread (a "lost unpark").
*
* <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
* non-reentrant lock class:
@ -98,26 +103,33 @@ package java.util.concurrent.locks;
*
* public void lock() {
* boolean wasInterrupted = false;
* Thread current = Thread.currentThread();
* waiters.add(current);
* // publish current thread for unparkers
* waiters.add(Thread.currentThread());
*
* // Block while not first in queue or cannot acquire lock
* while (waiters.peek() != current ||
* while (waiters.peek() != Thread.currentThread() ||
* !locked.compareAndSet(false, true)) {
* LockSupport.park(this);
* if (Thread.interrupted()) // ignore interrupts while waiting
* // ignore interrupts while waiting
* if (Thread.interrupted())
* wasInterrupted = true;
* }
*
* waiters.remove();
* if (wasInterrupted) // reassert interrupt status on exit
* current.interrupt();
* // ensure correct interrupt status on return
* if (wasInterrupted)
* Thread.currentThread().interrupt();
* }
*
* public void unlock() {
* locked.set(false);
* LockSupport.unpark(waiters.peek());
* }
*
* static {
* // Reduce the risk of "lost unpark" due to classloading
* Class<?> ensureLoaded = LockSupport.class;
* }
* }}</pre>
*/
public class LockSupport {

View File

@ -188,9 +188,9 @@ import java.util.concurrent.TimeUnit;
* try { return m.get(key); }
* finally { r.unlock(); }
* }
* public String[] allKeys() {
* public List<String> allKeys() {
* r.lock();
* try { return m.keySet().toArray(); }
* try { return new ArrayList<>(m.keySet()); }
* finally { r.unlock(); }
* }
* public Data put(String key, Data value) {

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch;
import java.nio.channels.spi.SelectorProvider;
/**
* Creates this platform's default SelectorProvider
*/
public class DefaultSelectorProvider {
/**
* Prevent instantiation.
*/
private DefaultSelectorProvider() { }
/**
* Returns the default SelectorProvider.
*/
public static SelectorProvider create() {
return new sun.nio.ch.DevPollSelectorProvider();
}
}

View File

@ -1587,4 +1587,119 @@ throws SQLException;
default void endRequest() throws SQLException {
// Default method takes no action
}
/**
* Sets and validates the sharding keys for this connection.
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
*
* @apiNote
* This method validates that the sharding keys are valid for the
* {@code Connection}. The timeout value indicates how long the driver
* should wait for the {@code Connection} to verify that the sharding key
* is valid before {@code setShardingKeyIfValid} returns false.
* @param shardingKey the sharding key to be validated against this connection
* @param superShardingKey the super sharding key to be validated against this
* connection. The super sharding key may be {@code null}.
* @param timeout time in seconds before which the validation process is expected to
* be completed, otherwise the validation process is aborted. A value of 0 indicates
* the validation process will not time out.
* @return true if the connection is valid and the sharding keys are valid
* and set on this connection; false if the sharding keys are not valid or
* the timeout period expires before the operation completes.
* @throws SQLException if an error occurs while performing this validation;
* the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified
* without a {@code shardingKey};
* this method is called on a closed {@code connection}; or
* the {@code timeout} value is less than 0.
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default boolean setShardingKeyIfValid(ShardingKey shardingKey,
ShardingKey superShardingKey, int timeout)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
}
/**
* Sets and validates the sharding key for this connection.
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method validates that the sharding key is valid for the
* {@code Connection}. The timeout value indicates how long the driver
* should wait for the {@code Connection} to verify that the sharding key
* is valid before {@code setShardingKeyIfValid} returns false.
* @param shardingKey the sharding key to be validated against this connection
* @param timeout time in seconds before which the validation process is expected to
* be completed,else the validation process is aborted. A value of 0 indicates
* the validation process will not time out.
* @return true if the connection is valid and the sharding key is valid to be
* set on this connection; false if the sharding key is not valid or
* the timeout period expires before the operation completes.
* @throws SQLException if there is an error while performing this validation;
* this method is called on a closed {@code connection}; the {@code shardingkey}
* is {@code null}; or the {@code timeout} value is less than 0.
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
}
/**
* Specifies a shardingKey and superShardingKey to use with this Connection
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method sets the specified sharding keys but does not require a
* round trip to the database to validate that the sharding keys are valid
* for the {@code Connection}.
* @param shardingKey the sharding key to set on this connection.
* @param superShardingKey the super sharding key to set on this connection.
* The super sharding key may be {@code null}
* @throws SQLException if an error occurs setting the sharding keys;
* this method is called on a closed {@code connection};
* the {@code shardingkey} is {@code null}; or
* a {@code superSharedingKey} is specified without a {@code shardingKey}
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
}
/**
* Specifies a shardingKey to use with this Connection
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method sets the specified sharding key but does not require a
* round trip to the database to validate that the sharding key is valid
* for the {@code Connection}.
* @param shardingKey the sharding key to set on this connection.
* @throws SQLException if an error occurs setting the sharding key;
* this method is called on a closed {@code connection}; or the
* {@code shardkingKey} is {@code null}
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default void setShardingKey(ShardingKey shardingKey)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.sql;
/**
* A builder created from a {@code DataSource} object,
* used to establish a connection to the database that the
* {@code data source} object represents. The connection
* properties that were specified for the {@code data source} are used as the
* default values by the {@code ConnectionBuilder}.
* <p>The following example illustrates the use of {@code ConnectionBuilder}
* to create a {@link Connection}:
*
* <pre>{@code
* DataSource ds = new MyDataSource();
* ShardingKey superShardingKey = ds.createShardingKeyBuilder()
* .subkey("EASTERN_REGION", JDBCType.VARCHAR)
* .build();
* ShardingKey shardingKey = ds.createShardingKeyBuilder()
* .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
* .build();
* Connection con = ds.createConnectionBuilder()
* .user("rafa")
* .password("tennis")
* .setShardingKey(shardingKey)
* .setSuperShardingKey(superShardingKey)
* .build();
* }</pre>
*
* @since 1.9
*
*/
public interface ConnectionBuilder {
/**
* Specifies the username to be used when creating a connection
*
* @param username the database user on whose behalf the connection is being
* made
* @return the same {@code ConnectionBuilder} instance
*/
ConnectionBuilder user(String username);
/**
* Specifies the password to be used when creating a connection
*
* @param password the password to use for this connection. May be {@code null}
* @return the same {@code ConnectionBuilder} instance
*/
ConnectionBuilder password(String password);
/**
* Specifies a {@code shardingKey} to be used when creating a connection
*
* @param shardingKey the ShardingKey. May be {@code null}
* @return the same {@code ConnectionBuilder} instance
* @see ShardingKey
* @see ShardingKeyBuilder
*/
ConnectionBuilder shardingKey(ShardingKey shardingKey);
/**
* Specifies a {@code superShardingKey} to be used when creating a connection
*
* @param superShardingKey the SuperShardingKey. May be {@code null}
* @return the same {@code ConnectionBuilder} instance
* @see ShardingKey
* @see ShardingKeyBuilder
*/
ConnectionBuilder superShardingKey(ShardingKey superShardingKey);
/**
* Returns an instance of the object defined by this builder.
*
* @return The built object
* @throws java.sql.SQLException If an error occurs building the object
*/
Connection build() throws SQLException;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -3684,4 +3684,19 @@ public interface DatabaseMetaData extends Wrapper {
return false;
}
// JDBC 4.3
/**
* Retrieves whether this database supports sharding.
* @implSpec
* The default implementation will return {@code false}
*
* @return {@code true} if this database supports sharding;
* {@code false} otherwise
* @exception SQLException if a database access error occurs
* @since 1.9
*/
default boolean supportsSharding() throws SQLException {
return false;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.sql;
/**
* Interface used to indicate that this object represents a Sharding Key. A
* {@code ShardingKey} instance is only guaranteed to be compatible with the
* data source instance that it was derived from. A {@code ShardingKey} is
* created using {@link ShardingKeyBuilder}.
* <p>
* The following example illustrates the use of {@link ShardingKeyBuilder} to
* create a {@code ShardingKey}:
* <pre>
* {@code
*
* DataSource ds = new MyDataSource();
* ShardingKey shardingKey = ds.createShardingKeyBuilder()
* .subkey("abc", JDBCType.VARCHAR)
* .subkey(94002, JDBCType.INTEGER)
* .build();
* }
* </pre>
* <p>
*
* A {@code ShardingKey} may also be used for specifying a
* {@code superShardingKey}. Databases that support composite Sharding may use a
* {@code superShardingKey} to specify a additional level of partitioning within
* the Shard.
* <p>
* The following example illustrates the use of {@link ShardingKeyBuilder} to
* create a {@code superShardingKey} for an eastern region with a
* {@code ShardingKey} specified for the Pittsburgh branch office:
* <pre>
* {@code
*
* DataSource ds = new MyDataSource();
* ShardingKey superShardingKey = ds.createShardingKeyBuilder()
* .subkey("EASTERN_REGION", JDBCType.VARCHAR)
* .build();
* ShardingKey shardingKey = ds.createShardingKeyBuilder()
* .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
* .build();
* Connection con = ds.createConnectionBuilder()
* .superShardingKey(superShardingKey)
* .shardingKey(shardingKey)
* .build();
* }
* </pre>
*
* @since 1.9
*/
public interface ShardingKey {
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.sql;
/**
* A builder created from a {@code DataSource} or {@code XADataSource} object,
* used to create a {@link ShardingKey} with sub-keys of supported data types.
* Implementations must
* support JDBCType.VARCHAR and may also support additional data types.
* <p>
* The following example illustrates the use of {@code ShardingKeyBuilder} to
* create a {@link ShardingKey}:
* <pre>
* {@code
*
* DataSource ds = new MyDataSource();
* ShardingKey shardingKey = ds.createShardingKeyBuilder()
* .subkey("abc", JDBCType.VARCHAR)
* .subkey(94002, JDBCType.INTEGER)
* .build();
* }
* </pre>
*/
public interface ShardingKeyBuilder {
/**
* This method will be called to add a subkey into a Sharding Key object being
* built. The order in which subkey method is called is important as it
* indicates the order of placement of the subkey within the Sharding Key.
*
* @param subkey contains the object that needs to be part of shard sub key
* @param subkeyType sub-key data type of type java.sql.SQLType
* @return this builder object
*/
ShardingKeyBuilder subkey(Object subkey, SQLType subkeyType);
/**
* Returns an instance of the object defined by this builder.
*
* @return The built object
* @throws java.sql.SQLException If an error occurs building the object
*/
ShardingKey build() throws SQLException;
}

View File

@ -1397,9 +1397,10 @@ public interface Statement extends Wrapper, AutoCloseable {
* @param val a character string
* @return A string enclosed by single quotes with every single quote
* converted to two single quotes
* @throws NullPointerException if val is null
* @throws NullPointerException if val is {@code null}
* @throws SQLException if a database access error occurs
*/
default String enquoteLiteral(String val) {
default String enquoteLiteral(String val) throws SQLException {
return "'" + val.replace("'", "''") + "'";
}
@ -1437,7 +1438,7 @@ public interface Statement extends Wrapper, AutoCloseable {
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
* <li>{@code identifier} contains a null character or double quote, and is not
* <li>{@code identifier} contains a {@code null} character or double quote and is not
* a simple SQL identifier.</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
@ -1501,14 +1502,14 @@ public interface Statement extends Wrapper, AutoCloseable {
* @throws SQLException if identifier is not a valid identifier
* @throws SQLFeatureNotSupportedException if the datasource does not support
* delimited identifiers
* @throws NullPointerException if identifier is null
* @throws NullPointerException if identifier is {@code null}
*/
default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException {
int len = identifier.length();
if (len < 1 || len > 128) {
throw new SQLException("Invalid name");
}
if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]+").matcher(identifier).matches()) {
if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches()) {
return alwaysQuote ? "\"" + identifier + "\"" : identifier;
}
if (identifier.matches("^\".+\"$")) {
@ -1520,4 +1521,65 @@ public interface Statement extends Wrapper, AutoCloseable {
throw new SQLException("Invalid name");
}
}
/**
* Retrieves whether {@code identifier} is a simple SQL identifier.
*
* @implSpec The default implementation uses the following criteria to
* determine a valid simple SQL identifier:
* <ul>
* <li>The string is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a through z, or
* from A through Z</li>
* <li>The string only contains alphanumeric characters or the character
* "_"</li>
* <li>The string is between 1 and 128 characters in length inclusive</li>
* </ul>
*
* <blockquote>
* <table border = 1 cellspacing=0 cellpadding=5 >
* <caption>Examples of the conversion:</caption>
* <tr>
* <th>identifier</th>
* <th>Simple Identifier</th>
*
* <tr>
* <td align='center'>Hello</td>
* <td align='center'>true</td>
* </tr>
* <tr>
* <td align='center'>G'Day</td>
* <td align='center'>false</td>
* </tr>
* <tr>
* <td align='center'>"Bruce Wayne"</td>
* <td align='center'>false</td>
* </tr>
* <tr>
* <td align='center'>GoodDay$</td>
* <td align='center'>false</td>
* </tr>
* <tr>
* <td align='center'>Hello"World</td>
* <td align='center'>false</td>
* </tr>
* <tr>
* <td align='center'>"Hello"World"</td>
* <td align='center'>false</td>
* </tr>
* </table>
* </blockquote>
* @implNote JDBC driver implementations may need to provide their own
* implementation of this method in order to meet the requirements of the
* underlying datasource.
* @param identifier a SQL identifier
* @return true if a simple SQL identifier, false otherwise
* @throws NullPointerException if identifier is {@code null}
* @throws SQLException if a database access error occurs
*/
default boolean isSimpleIdentifier(String identifier) throws SQLException {
int len = identifier.length();
return len >= 1 && len <= 128
&& Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
}
}

View File

@ -26,7 +26,10 @@
package javax.sql;
import java.sql.Connection;
import java.sql.ConnectionBuilder;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.ShardingKeyBuilder;
import java.sql.Wrapper;
/**
@ -106,4 +109,35 @@ public interface DataSource extends CommonDataSource, Wrapper {
*/
Connection getConnection(String username, String password)
throws SQLException;
// JDBC 4.3
/**
* Create a new {@code ConnectionBuilder} instance
* @implSpec
* The default implementation will throw a {@code SQLFeatureNotSupportedException}
* @return The ConnectionBuilder instance that was created
* @throws SQLException if an error occurs creating the builder
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see createConnectionBuilder
*/
default ConnectionBuilder createConnectionBuilder() throws SQLException {
throw new SQLFeatureNotSupportedException("createConnectionBuilder not implemented");
};
/**
* Create a new {@code ShardingKeyBuilder} instance
* @implSpec
* The default implementation will throw a {@code SQLFeatureNotSupportedException}
* @return The ShardingKeyBuilder instance that was created
* @throws SQLException if an error occurs creating the builder
* @throws SQLFeatureNotSupportedException if the driver does not support this method
* @since 1.9
* @see ShardingKeyBuilder
*/
default ShardingKeyBuilder createShardingKeyBuilder()
throws SQLException {
throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented");
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,40 +22,151 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.sql;
import java.sql.*;
/**
* An object that provides support for distributed
* transactions. An <code>XAConnection</code> object may be enlisted
* in a distributed transaction by means of an <code>XAResource</code> object.
* A transaction manager, usually part of a middle tier server, manages an
* <code>XAConnection</code> object through the <code>XAResource</code> object.
* An object that provides support for distributed transactions. An
* {@code XAConnection} object may be enlisted in a distributed transaction
* by means of an {@code XAResource} object. A transaction manager, usually
* part of a middle tier server, manages an {@code XAConnection} object
* through the {@code XAResource} object.
* <P>
* An application programmer does not use this interface directly; rather,
* it is used by a transaction manager working in the middle tier server.
* An application programmer does not use this interface directly; rather, it is
* used by a transaction manager working in the middle tier server.
*
* @since 1.4
*/
public interface XAConnection extends PooledConnection {
/**
* Retrieves an {@code XAResource} object that the transaction manager
* will use to manage this {@code XAConnection} object's participation
* in a distributed transaction.
*
* @return the {@code XAResource} object
* @exception SQLException if a database access error occurs
* @exception SQLFeatureNotSupportedException if the JDBC driver does not
* support this method
* @since 1.4
*/
javax.transaction.xa.XAResource getXAResource() throws SQLException;
/**
* Retrieves an <code>XAResource</code> object that
* the transaction manager will use
* to manage this <code>XAConnection</code> object's participation in a
* distributed transaction.
*
* @return the <code>XAResource</code> object
* @exception SQLException if a database access error occurs
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since 1.4
*/
javax.transaction.xa.XAResource getXAResource() throws SQLException;
// JDBC 4.3
}
/**
* Sets and validates the sharding keys for this connection.
*
* @implSpec The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
*
* @apiNote This method validates that the sharding keys are valid for the
* {@code Connection}. The timeout value indicates how long the driver
* should wait for the {@code Connection} to verify that the sharding key is
* valid before {@code setShardingKeyIfValid} returns false.
* @param shardingKey the sharding key to be validated against this
* connection
* @param superShardingKey the super sharding key to be validated against
* this connection. The super sharding key may be {@code null}.
* @param timeout time in seconds before which the validation process is
* expected to be completed, otherwise the validation process is aborted. A
* value of 0 indicates the validation process will not time out.
* @return true if the connection is valid and the sharding keys are valid
* and set on this connection; false if the sharding keys are not valid or
* the timeout period expires before the operation completes.
* @throws SQLException if an error occurs while performing this validation;
* the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified
* without a {@code shardingKey}; this method is called on a closed
* {@code connection}; or the {@code timeout} value is less than 0.
* @throws SQLFeatureNotSupportedException if the driver does not support
* sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default boolean setShardingKeyIfValid(ShardingKey shardingKey,
ShardingKey superShardingKey, int timeout)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
}
/**
* Sets and validates the sharding key for this connection.
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method validates that the sharding key is valid for the
* {@code Connection}. The timeout value indicates how long the driver
* should wait for the {@code Connection} to verify that the sharding key
* is valid before {@code setShardingKeyIfValid} returns false.
* @param shardingKey the sharding key to be validated against this connection
* @param timeout time in seconds before which the validation process is expected to
* be completed,else the validation process is aborted. A value of 0 indicates
* the validation process will not time out.
* @return true if the connection is valid and the sharding key is valid to be
* set on this connection; false if the sharding key is not valid or
* the timeout period expires before the operation completes.
* @throws SQLException if there is an error while performing this validation;
* this method is called on a closed {@code connection}; the {@code shardingkey}
* is {@code null}; or the {@code timeout} value is less than 0.
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
}
/**
* Specifies a shardingKey and superShardingKey to use with this Connection
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method sets the specified sharding keys but does not require a
* round trip to the database to validate that the sharding keys are valid
* for the {@code Connection}.
* @param shardingKey the sharding key to set on this connection.
* @param superShardingKey the super sharding key to set on this connection.
* The super sharding key may be {@code null}
* @throws SQLException if an error occurs setting the sharding keys;
* this method is called on a closed {@code connection};
* the {@code shardingkey} is {@code null}; or
* a {@code superSharedingKey} is specified without a {@code shardingKey}
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
}
/**
* Specifies a shardingKey to use with this Connection
* @implSpec
* The default implementation will throw a
* {@code SQLFeatureNotSupportedException}.
* @apiNote
* This method sets the specified sharding key but does not require a
* round trip to the database to validate that the sharding key is valid
* for the {@code Connection}.
* @param shardingKey the sharding key to set on this connection.
* @throws SQLException if an error occurs setting the sharding key;
* this method is called on a closed {@code connection}; or the
* {@code shardkingKey} is {@code null}
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see ShardingKey
* @see ShardingKeyBuilder
*/
default void setShardingKey(ShardingKey shardingKey)
throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.sql;
import java.sql.SQLException;
import java.sql.ShardingKey;
/**
* A builder created from a {@code XADataSource} object,
* used to establish a connection to the database that the
* {@code data source} object represents. The connection
* properties that were specified for the {@code data source} are used as the
* default values by the {@code XAConnectionBuilder}.
* <p>The following example illustrates the use of {@code XAConnectionBuilder}
* to create a {@link XAConnection}:
*
* <pre>{@code
* DataSource ds = new MyDataSource();
* ShardingKey superShardingKey = ds.createShardingKeyBuilder()
* .subkey("EASTERN_REGION", JDBCType.VARCHAR)
* .build();
* ShardingKey shardingKey = ds.createShardingKeyBuilder()
* .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
* .build();
* XAConnection con = ds.createXAConnectionBuilder()
* .user("rafa")
* .password("tennis")
* .setShardingKey(shardingKey)
* .setSuperShardingKey(superShardingKey)
* .build();
* }</pre>
*
* @since 1.9
*
*/
public interface XAConnectionBuilder {
/**
* Specifies the username to be used when creating a connection
*
* @param username the database user on whose behalf the connection is being
* made
* @return the same {@code XAConnectionBuilder} instance
*/
XAConnectionBuilder user(String username);
/**
* Specifies the password to be used when creating a connection
*
* @param password the password to use for this connection. May be {@code null}
* @return the same {@code XAConnectionBuilder} instance
*/
XAConnectionBuilder password(String password);
/**
* Specifies a {@code shardingKey} to be used when creating a connection
*
* @param shardingKey the ShardingKey. May be {@code null}
* @return the same {@code XAConnectionBuilder} instance
* @see java.sql.ShardingKey
* @see java.sql.ShardingKeyBuilder
*/
XAConnectionBuilder shardingKey(ShardingKey shardingKey);
/**
* Specifies a {@code superShardingKey} to be used when creating a connection
*
* @param superShardingKey the SuperShardingKey. May be {@code null}
* @return the same {@code XAConnectionBuilder} instance
* @see java.sql.ShardingKey
* @see java.sql.ShardingKeyBuilder
*/
XAConnectionBuilder superShardingKey(ShardingKey superShardingKey);
/**
* Returns an instance of the object defined by this builder.
*
* @return The built object
* @throws java.sql.SQLException If an error occurs building the object
*/
XAConnection build() throws SQLException;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -80,4 +80,35 @@ public interface XADataSource extends CommonDataSource {
*/
XAConnection getXAConnection(String user, String password)
throws SQLException;
// JDBC 4.3
/**
* Creates a new {@code XAConnectionBuilder} instance
* @implSpec
* The default implementation will throw a {@code SQLFeatureNotSupportedException}.
* @return The ConnectionBuilder instance that was created
* @throws SQLException if an error occurs creating the builder
* @throws SQLFeatureNotSupportedException if the driver does not support sharding
* @since 1.9
* @see XAConnectionBuilder
*/
default XAConnectionBuilder createXAConnectionBuilder() throws SQLException {
throw new SQLFeatureNotSupportedException("createXAConnectionBuilder not implemented");
};
/**
* Creates a new {@code ShardingKeyBuilder} instance
* @implSpec
* The default implementation will throw a {@code SQLFeatureNotSupportedException}.
* @return The ShardingKeyBuilder instance that was created
* @throws SQLException if an error occurs creating the builder
* @throws SQLFeatureNotSupportedException if the driver does not support this method
* @since 1.9
* @see ShardingKeyBuilder
*/
default ShardingKeyBuilder createShardingKeyBuilder()
throws SQLException {
throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented");
};
}

View File

@ -389,10 +389,22 @@ abstract class KeyStore extends KeyStoreSpi {
}
}
X509Certificate[] xchain;
if (chain != null) {
if (chain instanceof X509Certificate[]) {
xchain = (X509Certificate[]) chain;
} else {
xchain = new X509Certificate[chain.length];
System.arraycopy(chain, 0, xchain, 0, chain.length);
}
} else {
xchain = null;
}
if (! found) {
entry =
//TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
new KeyEntry(alias, null, (X509Certificate[]) chain);
new KeyEntry(alias, null, xchain);
entries.add(entry);
}
@ -400,7 +412,7 @@ abstract class KeyStore extends KeyStoreSpi {
try {
entry.setPrivateKey((RSAPrivateCrtKey) key);
entry.setCertificateChain((X509Certificate[]) chain);
entry.setCertificateChain(xchain);
} catch (CertificateException ce) {
throw new KeyStoreException(ce);

View File

@ -0,0 +1 @@
sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService

View File

@ -1,3 +1,2 @@
sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService
sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService
sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService

View File

@ -26,11 +26,8 @@
package sun.jvmstat.perfdata.monitor;
import java.util.List;
import java.lang.reflect.*;
import java.io.*;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.remote.*;
import sun.jvmstat.monitor.event.VmListener;
/**

View File

@ -31,7 +31,7 @@ import jdk.testlibrary.Utils;
*
* @library /lib/testlibrary
* @modules java.management
* @build jdk.testlibarary.*
* @build jdk.testlibrary.*
* @build DoubleAgentTest Exit0
* @run driver DoubleAgentTest
*/

View File

@ -29,7 +29,7 @@ import jdk.testlibrary.ProcessTools;
* @summary Test for JDWP: -agentlib:jdwp=suspend=n hanging
* @library /lib/testlibrary
* @modules java.management
* @build jdk.testlibarary.*
* @build jdk.testlibrary.*
* @compile -g HelloWorld.java
* @run driver SuspendNoFlagTest
*/

View File

@ -41,9 +41,9 @@ import com.sun.management.HotSpotDiagnosticMXBean;
* @library /test/lib/share/classes
* @build jdk.testlibrary.*
* @build jdk.test.lib.hprof.*
* @build jdk.test.lib.hprof.module.*
* @build jdk.test.lib.hprof.model.*
* @build jdk.test.lib.hprof.parser.*
* @build jdk.test.lib.hprof.utils.*
* @build jdk.test.lib.hprof.util.*
* @run main DumpHeap
*/
public class DumpHeap {

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8136500
* @summary Test Integer.toString method
*/
public class ToString {
public static void main(String[] args) throws Exception {
test("-2147483648", Integer.MIN_VALUE);
test("2147483647", Integer.MAX_VALUE);
test("0", 0);
// Wiggle around the exponentially increasing base.
final int LIMIT = (1 << 15);
int base = 10000;
while (base < Integer.MAX_VALUE / 10) {
for (int d = -LIMIT; d < LIMIT; d++) {
int c = base + d;
if (c > 0) {
buildAndTest(c);
}
}
base *= 10;
}
for (int c = 1; c < LIMIT; c++) {
buildAndTest(Integer.MAX_VALUE - LIMIT + c);
}
}
private static void buildAndTest(int c) {
if (c <= 0) {
throw new IllegalArgumentException("Test bug: can only handle positives, " + c);
}
StringBuilder sbN = new StringBuilder();
StringBuilder sbP = new StringBuilder();
int t = c;
while (t > 0) {
char digit = (char) ('0' + (t % 10));
sbN.append(digit);
sbP.append(digit);
t = t / 10;
}
sbN.append("-");
sbN.reverse();
sbP.reverse();
test(sbN.toString(), -c);
test(sbP.toString(), c);
}
private static void test(String expected, int value) {
String actual = Integer.toString(value);
if (!expected.equals(actual)) {
throw new RuntimeException("Expected " + expected + ", but got " + actual);
}
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8136500
* @summary Test Long.toString method
*/
public class ToString {
public static void main(String[] args) throws Exception {
test("-9223372036854775808", Long.MIN_VALUE);
test("9223372036854775807", Long.MAX_VALUE);
test("0", 0);
// Wiggle around the exponentially increasing base.
final int LIMIT = (1 << 15);
long base = 10000;
while (base < Long.MAX_VALUE / 10) {
for (int d = -LIMIT; d < LIMIT; d++) {
long c = base + d;
if (c > 0) {
buildAndTest(c);
}
}
base *= 10;
}
for (int c = 1; c < LIMIT; c++) {
buildAndTest(Long.MAX_VALUE - LIMIT + c);
}
}
private static void buildAndTest(long c) {
if (c <= 0) {
throw new IllegalArgumentException("Test bug: can only handle positives, " + c);
}
StringBuilder sbN = new StringBuilder();
StringBuilder sbP = new StringBuilder();
long t = c;
while (t > 0) {
char digit = (char) ('0' + (t % 10));
sbN.append(digit);
sbP.append(digit);
t = t / 10;
}
sbN.append("-");
sbN.reverse();
sbP.reverse();
test(sbN.toString(), -c);
test(sbP.toString(), c);
}
private static void test(String expected, long value) {
String actual = Long.toString(value);
if (!expected.equals(actual)) {
throw new RuntimeException("Expected " + expected + ", but got " + actual);
}
}
}

View File

@ -34,6 +34,7 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;
import java.util.*;
import static java.lang.invoke.MethodType.methodType;
@ -412,6 +413,18 @@ public class T8139885 {
assertEquals(illegalPos.length, caught);
}
@Test
public static void testAsSpreaderIllegalMethodType() throws Throwable {
MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class);
boolean caught = false;
try {
MethodHandle s = h.asSpreader(String[].class, 1);
} catch (WrongMethodTypeException wmte) {
caught = true;
}
assertTrue(caught);
}
@Test
public static void testAsCollector() throws Throwable {
MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);

View File

@ -24,6 +24,7 @@ package test.sql;
import java.sql.SQLException;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -33,18 +34,29 @@ import util.StubStatement;
public class StatementTests extends BaseTest {
protected StubStatement stmt;
protected static String maxIdentifier;
@BeforeMethod
public void setUpMethod() throws Exception {
stmt = new StubStatement();
}
@BeforeClass
public static void setUpClass() throws Exception {
int maxLen = 128;
StringBuilder s = new StringBuilder(maxLen);
for (int i = 0; i < maxLen; i++) {
s.append('a');
}
maxIdentifier = s.toString();
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedLiteralValues")
public void test00(String s, String expected) {
public void test00(String s, String expected) throws SQLException {
assertEquals(stmt.enquoteLiteral(s), expected);
}
@ -53,7 +65,7 @@ public class StatementTests extends BaseTest {
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test01() {
public void test01() throws SQLException {
stmt.enquoteLiteral(null);
}
@ -89,6 +101,24 @@ public class StatementTests extends BaseTest {
}
/*
* Validate that isSimpleIdentifier returns the expected value
*/
@Test(dataProvider = "simpleIdentifierValues")
public void test05(String s, boolean expected) throws SQLException {
assertEquals(stmt.isSimpleIdentifier(s), expected);
}
/*
* Validate a NullPointerException is thrown is the string passed to
* isSimpleIdentifier is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test06() throws SQLException {
stmt.isSimpleIdentifier(null);
}
/*
* DataProvider used to provide strings that will be used to validate
* that enquoteLiteral converts a string to a literal and every instance of
@ -114,6 +144,10 @@ public class StatementTests extends BaseTest {
@DataProvider(name = "validIdentifierValues")
protected Object[][] validEnquotedIdentifierValues() {
return new Object[][]{
{"b", false, "b"},
{"b", true, "\"b\""},
{maxIdentifier, false, maxIdentifier},
{maxIdentifier, true, "\"" + maxIdentifier + "\""},
{"Hello", false, "Hello"},
{"Hello", true, "\"Hello\""},
{"G'Day", false, "\"G'Day\""},
@ -130,16 +164,34 @@ public class StatementTests extends BaseTest {
*/
@DataProvider(name = "invalidIdentifierValues")
protected Object[][] invalidEnquotedIdentifierValues() {
int invalidLen = 129;
StringBuilder s = new StringBuilder(invalidLen);
for (int i = 0; i < invalidLen; i++) {
s.append('a');
}
return new Object[][]{
{"Hel\"lo", false},
{"\"Hel\"lo\"", true},
{"Hello" + '\0', false},
{"", false},
{s.toString(), false},};
{maxIdentifier + 'a', false},
};
}
/*
* DataProvider used to provide strings that will be used to validate
* that isSimpleIdentifier returns the correct value based on the
* identifier specified.
*/
@DataProvider(name = "simpleIdentifierValues")
protected Object[][] simpleIdentifierValues() {
return new Object[][]{
{"b", true},
{"Hello", true},
{"\"Gotham\"", false},
{"G'Day", false},
{"Bruce Wayne", false},
{"GoodDay$", false},
{"Dick_Grayson", true},
{"Batmobile1966", true},
{maxIdentifier, true},
{maxIdentifier + 'a', false},
{"", false},};
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 4904067 5023830 7129185
* @bug 4904067 5023830 7129185 8072015
* @summary Unit test for Collections.checkedMap
* @author Josh Bloch
* @run testng CheckedMapBash
@ -53,7 +53,7 @@ public class CheckedMapBash {
Object newHead;
do {
newHead = new Integer(rnd.nextInt());
} while (m.containsKey(newHead));
} while (m.containsKey(newHead) || newHead.equals(nil));
m.put(newHead, head);
head = newHead;
}
@ -99,16 +99,16 @@ public class CheckedMapBash {
}
@Test(dataProvider = "Supplier<Map<Integer,Integer>>")
public static void testCheckeMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
Map m = supplier.get();
for (int i=0; i<mapSize; i++)
if (m.put(new Integer(i), new Integer(2*i)) != null)
fail("put returns a non-null value erroenously.");
fail("put returns a non-null value erroneously.");
for (int i=0; i<2*mapSize; i++)
if (m.containsValue(new Integer(i)) != (i%2==0))
fail("contains value "+i);
if (m.put(nil, nil) == null)
fail("put returns a null value erroenously.");
fail("put returns a null value erroneously.");
Map m2 = supplier.get(); m2.putAll(m);
if (!m.equals(m2))
fail("Clone not equal to original. (1)");
@ -147,7 +147,7 @@ public class CheckedMapBash {
ArrayList<Object[]> iters = new ArrayList<>(makeCheckedMaps());
iters.ensureCapacity(numItr * iters.size());
for (int each=1; each < numItr; each++) {
iters.addAll( makeCheckedMaps());
iters.addAll(makeCheckedMaps());
}
return iters.iterator();
}
@ -158,19 +158,20 @@ public class CheckedMapBash {
}
public static Collection<Object[]> makeCheckedMaps() {
return Arrays.asList(
new Object[]{"Collections.checkedMap(HashMap)",
(Supplier) () -> {return Collections.checkedMap(new HashMap(), Integer.class, Integer.class);}},
new Object[]{"Collections.checkedMap(TreeSet(reverseOrder)",
(Supplier) () -> {return Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}},
new Object[]{"Collections.checkedMap(TreeSet).descendingSet()",
(Supplier) () -> {return Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}},
new Object[]{"Collections.checkedNavigableMap(TreeSet)",
(Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class);}},
new Object[]{"Collections.checkedNavigableMap(TreeSet(reverseOrder)",
(Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}},
new Object[]{"Collections.checkedNavigableMap().descendingSet()",
(Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}}
);
Object[][] params = {
{"Collections.checkedMap(HashMap)",
(Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)},
{"Collections.checkedMap(TreeMap(reverseOrder))",
(Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
{"Collections.checkedMap(TreeMap.descendingMap())",
(Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
{"Collections.checkedNavigableMap(TreeMap)",
(Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)},
{"Collections.checkedNavigableMap(TreeMap(reverseOrder))",
(Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
{"Collections.checkedNavigableMap(TreeMap.descendingMap())",
(Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
};
return Arrays.asList(params);
}
}

View File

@ -146,25 +146,26 @@ public class CheckedSetBash {
ArrayList<Object[]> iters = new ArrayList<>(makeCheckedSets());
iters.ensureCapacity(numItr * iters.size());
for (int each=1; each < numItr; each++) {
iters.addAll( makeCheckedSets());
iters.addAll(makeCheckedSets());
}
return iters.iterator();
}
public static Collection<Object[]> makeCheckedSets() {
return Arrays.asList(
new Object[]{"Collections.checkedSet(HashSet)",
(Supplier) () -> {return Collections.checkedSet(new HashSet(), Integer.class);}},
new Object[]{"Collections.checkedSet(TreeSet(reverseOrder)",
(Supplier) () -> {return Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class);}},
new Object[]{"Collections.checkedSet(TreeSet).descendingSet()",
(Supplier) () -> {return Collections.checkedSet(new TreeSet().descendingSet(), Integer.class);}},
new Object[]{"Collections.checkedNavigableSet(TreeSet)",
(Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(), Integer.class);}},
new Object[]{"Collections.checkedNavigableSet(TreeSet(reverseOrder)",
(Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class);}},
new Object[]{"Collections.checkedNavigableSet().descendingSet()",
(Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class);}}
);
Object[][] params = {
{"Collections.checkedSet(HashSet)",
(Supplier) () -> Collections.checkedSet(new HashSet(), Integer.class)},
{"Collections.checkedSet(TreeSet(reverseOrder))",
(Supplier) () -> Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
{"Collections.checkedSet(TreeSet.descendingSet())",
(Supplier) () -> Collections.checkedSet(new TreeSet().descendingSet(), Integer.class)},
{"Collections.checkedNavigableSet(TreeSet)",
(Supplier) () -> Collections.checkedNavigableSet(new TreeSet(), Integer.class)},
{"Collections.checkedNavigableSet(TreeSet(reverseOrder))",
(Supplier) () -> Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
{"Collections.checkedNavigableSet(TreeSet.descendingSet())",
(Supplier) () -> Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class)},
};
return Arrays.asList(params);
}
}

View File

@ -58,7 +58,7 @@ public class EmptyCollectionSerialization {
Object singleton = o.get();
assertSame(o.get(), singleton, description + ": broken Supplier not returning singleton");
Object copy = patheticDeepCopy(singleton);
assertSame( copy, singleton, description + ": " +
assertSame(copy, singleton, description + ": " +
copy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(copy)) +
" is not the singleton " +
singleton.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(singleton)));
@ -73,27 +73,28 @@ public class EmptyCollectionSerialization {
}
public static Collection<Object[]> makeSingletons() {
return Arrays.asList(
new Object[]{"Collections.EMPTY_LIST",
(Supplier) () -> {return Collections.EMPTY_LIST;}},
new Object[]{"Collections.EMPTY_MAP",
(Supplier) () -> {return Collections.EMPTY_MAP;}},
new Object[]{"Collections.EMPTY_SET",
(Supplier) () -> {return Collections.EMPTY_SET;}},
new Object[]{"Collections.singletonMap()",
(Supplier) () -> {return Collections.emptyList();}},
new Object[]{"Collections.emptyMap()",
(Supplier) () -> {return Collections.emptyMap();}},
new Object[]{"Collections.emptySet()",
(Supplier) () -> {return Collections.emptySet();}},
new Object[]{"Collections.emptySortedSet()",
(Supplier) () -> {return Collections.emptySortedSet();}},
new Object[]{"Collections.emptySortedMap()",
(Supplier) () -> {return Collections.emptySortedMap();}},
new Object[]{"Collections.emptyNavigableSet()",
(Supplier) () -> {return Collections.emptyNavigableSet();}},
new Object[]{"Collections.emptyNavigableMap()",
(Supplier) () -> {return Collections.emptyNavigableMap();}}
);
Object[][] params = {
{"Collections.EMPTY_LIST",
(Supplier) () -> Collections.EMPTY_LIST},
{"Collections.EMPTY_MAP",
(Supplier) () -> Collections.EMPTY_MAP},
{"Collections.EMPTY_SET",
(Supplier) () -> Collections.EMPTY_SET},
{"Collections.emptyList()",
(Supplier) () -> Collections.emptyList()},
{"Collections.emptyMap()",
(Supplier) () -> Collections.emptyMap()},
{"Collections.emptySet()",
(Supplier) () -> Collections.emptySet()},
{"Collections.emptySortedSet()",
(Supplier) () -> Collections.emptySortedSet()},
{"Collections.emptySortedMap()",
(Supplier) () -> Collections.emptySortedMap()},
{"Collections.emptyNavigableSet()",
(Supplier) () -> Collections.emptyNavigableSet()},
{"Collections.emptyNavigableMap()",
(Supplier) () -> Collections.emptyNavigableMap()},
};
return Arrays.asList(params);
}
}

View File

@ -1180,8 +1180,11 @@ public class LocaleEnhanceTest extends LocaleTestFmwk {
dataDir = new File(dataDirName);
}
if (dataDir == null || !dataDir.isDirectory()) {
errln("Could not locate the serialized test case data location");
if (dataDir == null) {
errln("'dataDir' is null. serialized.data.dir Property value is "+dataDirName);
return;
} else if (!dataDir.isDirectory()) {
errln("'dataDir' is not a directory. dataDir: "+dataDir.toString());
return;
}

View File

@ -22,7 +22,6 @@
*/
/*
@test
@ignore 6876961
@summary test that ResourceBundle.getBundle can be called recursively
@build Test4300693RB
@run main Test4300693

View File

@ -202,9 +202,9 @@ public class SpliteratorLateBindingFailFastTest {
db.addCollection(PriorityQueue::new);
// ArrayDeque fails some tests since it's fail-fast support is weaker
// ArrayDeque fails some tests since its fail-fast support is weaker
// than other collections and limited to detecting most, but not all,
// removals. It probably requires it's own test since it is difficult
// removals. It probably requires its own test since it is difficult
// to abstract out the conditions under which it fails-fast.
// db.addCollection(ArrayDeque::new);

View File

@ -85,7 +85,7 @@ import static org.testng.Assert.assertEquals;
@Test
public class SpliteratorTraversingAndSplittingTest {
private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 42);
private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE});
private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE});

View File

@ -34,150 +34,148 @@
/*
* @test
* @bug 4486658
* @run main/timeout=7000 CancelledProducerConsumerLoops
* @summary Checks for responsiveness of blocking queues to cancellation.
* Runs under the assumption that ITERS computations require more than
* TIMEOUT msecs to complete.
*/
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.List;
import java.util.SplittableRandom;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class CancelledProducerConsumerLoops {
static final int CAPACITY = 100;
static final long TIMEOUT = 100;
static final ExecutorService pool = Executors.newCachedThreadPool();
static boolean print = false;
static ExecutorService pool;
public static void main(String[] args) throws Exception {
int maxPairs = 8;
int iters = 1000000;
if (args.length > 0)
maxPairs = Integer.parseInt(args[0]);
print = true;
final int maxPairs = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) {
System.out.println("Pairs:" + i);
try {
oneTest(i, iters);
}
catch (BrokenBarrierException bb) {
// OK, ignore
}
Thread.sleep(100);
final List<BlockingQueue<Integer>> queues = new ArrayList<>();
queues.add(new ArrayBlockingQueue<Integer>(100));
queues.add(new LinkedBlockingQueue<Integer>(100));
queues.add(new LinkedBlockingDeque<Integer>(100));
queues.add(new SynchronousQueue<Integer>());
// unbounded queue implementations are prone to OOME:
// PriorityBlockingQueue, LinkedTransferQueue
for (BlockingQueue<Integer> queue : queues)
new CancelledProducerConsumerLoops(i, queue).run();
}
pool.shutdown();
if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
throw new Error();
}
if (! pool.awaitTermination(10L, TimeUnit.SECONDS))
throw new AssertionError("timed out");
pool = null;
}
static void oneRun(BlockingQueue<Integer> q, int npairs, int iters) throws Exception {
if (print)
System.out.printf("%-18s", q.getClass().getSimpleName());
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer);
final int npairs;
final BlockingQueue<Integer> queue;
final CountDownLatch producersInterrupted;
final CountDownLatch consumersInterrupted;
final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
final CyclicBarrier barrier;
final SplittableRandom rnd = new SplittableRandom();
volatile boolean done = false;
CancelledProducerConsumerLoops(int npairs, BlockingQueue<Integer> queue) {
this.npairs = npairs;
this.queue = queue;
this.producersInterrupted = new CountDownLatch(npairs - 1);
this.consumersInterrupted = new CountDownLatch(npairs - 1);
this.barrier = new CyclicBarrier(npairs * 2 + 1, timer);
}
void run() throws Exception {
Future<?>[] prods = new Future<?>[npairs];
Future<?>[] cons = new Future<?>[npairs];
for (int i = 0; i < npairs; ++i) {
prods[i] = pool.submit(new Producer(q, barrier, iters));
cons[i] = pool.submit(new Consumer(q, barrier, iters));
for (int i = 0; i < npairs; i++) {
prods[i] = pool.submit(new Producer());
cons[i] = pool.submit(new Consumer());
}
barrier.await();
Thread.sleep(TIMEOUT);
boolean tooLate = false;
Thread.sleep(rnd.nextInt(5));
for (int i = 1; i < npairs; ++i) {
if (!prods[i].cancel(true))
tooLate = true;
if (!cons[i].cancel(true))
tooLate = true;
for (int i = 1; i < npairs; i++) {
if (!prods[i].cancel(true) ||
!cons[i].cancel(true))
throw new AssertionError("completed before done");
}
Object p0 = prods[0].get();
Object c0 = cons[0].get();
if (!tooLate) {
for (int i = 1; i < npairs; ++i) {
if (!prods[i].isDone() || !prods[i].isCancelled())
throw new Error("Only one producer thread should complete");
if (!cons[i].isDone() || !cons[i].isCancelled())
throw new Error("Only one consumer thread should complete");
}
for (int i = 1; i < npairs; i++) {
assertCancelled(prods[i]);
assertCancelled(cons[i]);
}
else
System.out.print("(cancelled too late) ");
long endTime = System.nanoTime();
long time = endTime - timer.startTime;
if (print) {
double secs = (double)(time) / 1000000000.0;
System.out.println("\t " + secs + "s run time");
}
if (!producersInterrupted.await(10L, TimeUnit.SECONDS))
throw new AssertionError("timed out");
if (!consumersInterrupted.await(10L, TimeUnit.SECONDS))
throw new AssertionError("timed out");
if (prods[0].isDone() || prods[0].isCancelled())
throw new AssertionError("completed too early");
done = true;
if (! (prods[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
throw new AssertionError("expected Integer");
if (! (cons[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
throw new AssertionError("expected Integer");
}
static void oneTest(int pairs, int iters) throws Exception {
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
/* unbounded queue implementations are prone to OOME
oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4);
oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
*/
void assertCancelled(Future<?> future) throws Exception {
if (!future.isDone())
throw new AssertionError("not done");
if (!future.isCancelled())
throw new AssertionError("not cancelled");
try {
future.get(10L, TimeUnit.SECONDS);
throw new AssertionError("should throw CancellationException");
} catch (CancellationException success) {}
}
abstract static class Stage implements Callable<Integer> {
final BlockingQueue<Integer> queue;
final CyclicBarrier barrier;
final int iters;
Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
queue = q;
barrier = b;
this.iters = iters;
}
}
static class Producer extends Stage {
Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
class Producer implements Callable<Integer> {
public Integer call() throws Exception {
barrier.await();
int s = 0;
int l = 4321;
for (int i = 0; i < iters; ++i) {
l = LoopHelpers.compute1(l);
s += LoopHelpers.compute2(l);
if (!queue.offer(new Integer(l), 1, TimeUnit.SECONDS))
break;
int sum = 0;
try {
int x = 4321;
while (!done) {
if (Thread.interrupted()) throw new InterruptedException();
x = LoopHelpers.compute1(x);
sum += LoopHelpers.compute2(x);
queue.offer(new Integer(x), 1, TimeUnit.MILLISECONDS);
}
} catch (InterruptedException cancelled) {
producersInterrupted.countDown();
}
return new Integer(s);
return sum;
}
}
static class Consumer extends Stage {
Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
class Consumer implements Callable<Integer> {
public Integer call() throws Exception {
barrier.await();
int l = 0;
int s = 0;
for (int i = 0; i < iters; ++i) {
Integer x = queue.poll(1, TimeUnit.SECONDS);
if (x == null)
break;
l = LoopHelpers.compute1(x.intValue());
s += l;
int sum = 0;
try {
while (!done) {
Integer x = queue.poll(1, TimeUnit.MILLISECONDS);
if (x != null)
sum += LoopHelpers.compute1(x.intValue());
}
} catch (InterruptedException cancelled) {
consumersInterrupted.countDown();
}
return new Integer(s);
return sum;
}
}
}

View File

@ -37,8 +37,19 @@
* @summary Test drainTo failing due to c.add throwing
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.FutureTask;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@SuppressWarnings({"unchecked", "rawtypes"})
public class DrainToFails {

View File

@ -28,9 +28,19 @@
* @author Martin Buchholz
*/
import java.util.*;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class Interrupt {
@ -61,7 +71,7 @@ public class Interrupt {
checkInterrupted0(fs, immediateExecutor);
checkInterrupted0(fs, delayedExecutor);
stpe.shutdown();
check(stpe.awaitTermination(10, SECONDS));
check(stpe.awaitTermination(10L, SECONDS));
}
static void testQueue(final BlockingQueue<Object> q) {

View File

@ -28,8 +28,13 @@
* @author Martin Buchholz
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.Iterator;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
public class LastElement {
void test(String[] args) throws Throwable {

View File

@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.concurrent.atomic.AtomicLong;
/**
* Misc utilities in JSR166 performance tests
*/
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@ -74,28 +72,6 @@ class LoopHelpers {
return x;
}
/**
* An actually useful random number generator, but unsynchronized.
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
public void setSeed(long s) {
seed = s;
}
public int next() {
long nextseed = (seed * multiplier + addend) & mask;
seed = nextseed;
return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
}
}
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;

View File

@ -34,151 +34,124 @@
/*
* @test
* @bug 4486658
* @run main/timeout=3600 MultipleProducersSingleConsumerLoops
* @summary multiple producers and single consumer using blocking queues
*/
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class MultipleProducersSingleConsumerLoops {
static final int CAPACITY = 100;
static final ExecutorService pool = Executors.newCachedThreadPool();
static boolean print = false;
static int producerSum;
static int consumerSum;
static synchronized void addProducerSum(int x) {
producerSum += x;
}
static synchronized void addConsumerSum(int x) {
consumerSum += x;
}
static synchronized void checkSum() {
if (producerSum != consumerSum)
throw new Error("CheckSum mismatch");
}
static ExecutorService pool;
public static void main(String[] args) throws Exception {
int maxProducers = 5;
int iters = 100000;
if (args.length > 0)
maxProducers = Integer.parseInt(args[0]);
print = false;
System.out.println("Warmup...");
oneTest(1, 10000);
Thread.sleep(100);
oneTest(2, 10000);
Thread.sleep(100);
print = true;
final int maxProducers = (args.length > 0)
? Integer.parseInt(args[0])
: 5;
pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxProducers; i += (i+1) >>> 1) {
System.out.println("----------------------------------------");
System.out.println("Producers:" + i);
oneTest(i, iters);
Thread.sleep(100);
// Adjust iterations to limit typical single runs to <= 10 ms;
// Notably, fair queues get fewer iters.
// Unbounded queues can legitimately OOME if iterations
// high enough, but we have a sufficiently low limit here.
run(new ArrayBlockingQueue<Integer>(100), i, 300);
run(new LinkedBlockingQueue<Integer>(100), i, 700);
run(new LinkedBlockingDeque<Integer>(100), i , 500);
run(new LinkedTransferQueue<Integer>(), i, 1000);
run(new PriorityBlockingQueue<Integer>(), i, 1000);
run(new SynchronousQueue<Integer>(), i, 500);
run(new SynchronousQueue<Integer>(true), i, 200);
run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
if (! pool.awaitTermination(10L, SECONDS))
throw new Error();
}
static void oneTest(int producers, int iters) throws Exception {
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), producers, iters);
oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), producers, iters);
oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), producers, iters);
oneRun(new LinkedTransferQueue<Integer>(), producers, iters);
// Don't run PBQ since can legitimately run out of memory
// if (print)
// System.out.print("PriorityBlockingQueue ");
// oneRun(new PriorityBlockingQueue<Integer>(), producers, iters);
oneRun(new SynchronousQueue<Integer>(), producers, iters);
if (print)
System.out.println("fair implementations:");
oneRun(new SynchronousQueue<Integer>(true), producers, iters);
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), producers, iters);
pool = null;
}
abstract static class Stage implements Runnable {
final int iters;
final BlockingQueue<Integer> queue;
final CyclicBarrier barrier;
Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
queue = q;
barrier = b;
this.iters = iters;
}
static void run(BlockingQueue<Integer> queue, int nproducers, int iters) throws Exception {
new MultipleProducersSingleConsumerLoops(queue, nproducers, iters).run();
}
static class Producer extends Stage {
Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
final BlockingQueue<Integer> queue;
final int nproducers;
final int iters;
final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
final CyclicBarrier barrier;
final AtomicInteger checksum = new AtomicInteger(0);
Throwable fail;
public void run() {
try {
barrier.await();
int s = 0;
int l = hashCode();
for (int i = 0; i < iters; ++i) {
l = LoopHelpers.compute1(l);
l = LoopHelpers.compute2(l);
queue.put(new Integer(l));
s += l;
}
addProducerSum(s);
barrier.await();
}
catch (Exception ie) {
ie.printStackTrace();
return;
}
}
MultipleProducersSingleConsumerLoops(BlockingQueue<Integer> queue, int nproducers, int iters) {
this.queue = queue;
this.nproducers = nproducers;
this.iters = iters;
this.barrier = new CyclicBarrier(nproducers + 2, timer);
}
static class Consumer extends Stage {
Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
public void run() {
try {
barrier.await();
int s = 0;
for (int i = 0; i < iters; ++i) {
s += queue.take().intValue();
}
addConsumerSum(s);
barrier.await();
}
catch (Exception ie) {
ie.printStackTrace();
return;
}
}
}
static void oneRun(BlockingQueue<Integer> q, int nproducers, int iters) throws Exception {
if (print)
System.out.printf("%-18s", q.getClass().getSimpleName());
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(nproducers + 2, timer);
for (int i = 0; i < nproducers; ++i) {
pool.execute(new Producer(q, barrier, iters));
}
pool.execute(new Consumer(q, barrier, iters * nproducers));
void run() throws Exception {
for (int i = 0; i < nproducers; i++)
pool.execute(new Producer());
pool.execute(new Consumer());
barrier.await();
barrier.await();
long time = timer.getTime();
checkSum();
if (print)
System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nproducers)) + " ns per transfer");
System.out.printf("%s, nproducers=%d: %d ms%n",
queue.getClass().getSimpleName(), nproducers,
NANOSECONDS.toMillis(timer.getTime()));
if (checksum.get() != 0) throw new AssertionError("checksum mismatch");
if (fail != null) throw new AssertionError(fail);
}
abstract class CheckedRunnable implements Runnable {
abstract void realRun() throws Throwable;
public final void run() {
try {
realRun();
} catch (Throwable t) {
fail = t;
t.printStackTrace();
throw new AssertionError(t);
}
}
}
class Producer extends CheckedRunnable {
void realRun() throws Throwable {
barrier.await();
int s = 0;
int l = hashCode();
for (int i = 0; i < iters; i++) {
l = LoopHelpers.compute1(l);
l = LoopHelpers.compute2(l);
queue.put(new Integer(l));
s += l;
}
checksum.getAndAdd(s);
barrier.await();
}
}
class Consumer extends CheckedRunnable {
void realRun() throws Throwable {
barrier.await();
int s = 0;
for (int i = 0; i < nproducers * iters; i++) {
s += queue.take().intValue();
}
checksum.getAndAdd(-s);
barrier.await();
}
}
}

View File

@ -34,13 +34,20 @@
/*
* @test
* @bug 6805775 6815766
* @run main OfferDrainToLoops 300
* @run main OfferDrainToLoops 100
* @summary Test concurrent offer vs. drainTo
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.ArrayList;
import java.util.List;
import java.util.SplittableRandom;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.AtomicLong;
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class OfferDrainToLoops {
@ -66,22 +73,22 @@ public class OfferDrainToLoops {
test(new LinkedTransferQueue());
}
Random getRandom() {
return ThreadLocalRandom.current();
}
void test(final BlockingQueue q) throws Throwable {
System.out.println(q.getClass().getSimpleName());
final long testDurationNanos = testDurationMillis * 1000L * 1000L;
final long quittingTimeNanos = System.nanoTime() + testDurationNanos;
final long timeoutMillis = 10L * 1000L;
final SplittableRandom rnd = new SplittableRandom();
/** Poor man's bounded buffer. */
final AtomicLong approximateCount = new AtomicLong(0L);
abstract class CheckedThread extends Thread {
CheckedThread(String name) {
final SplittableRandom rnd;
CheckedThread(String name, SplittableRandom rnd) {
super(name);
this.rnd = rnd;
setDaemon(true);
start();
}
@ -99,7 +106,7 @@ public class OfferDrainToLoops {
}
}
Thread offerer = new CheckedThread("offerer") {
Thread offerer = new CheckedThread("offerer", rnd.split()) {
protected void realRun() {
long c = 0;
for (long i = 0; ! quittingTime(i); i++) {
@ -113,9 +120,8 @@ public class OfferDrainToLoops {
Thread.yield();
}}}};
Thread drainer = new CheckedThread("drainer") {
Thread drainer = new CheckedThread("drainer", rnd.split()) {
protected void realRun() {
final Random rnd = getRandom();
while (! quittingTime()) {
List list = new ArrayList();
int n = rnd.nextBoolean() ?
@ -131,9 +137,8 @@ public class OfferDrainToLoops {
approximateCount.set(0); // Releases waiting offerer thread
}};
Thread scanner = new CheckedThread("scanner") {
Thread scanner = new CheckedThread("scanner", rnd.split()) {
protected void realRun() {
final Random rnd = getRandom();
while (! quittingTime()) {
switch (rnd.nextInt(3)) {
case 0: checkNotContainsNull(q); break;
@ -157,8 +162,6 @@ public class OfferDrainToLoops {
failed++;
for (StackTraceElement e : thread.getStackTrace())
System.err.println(e);
// Kludge alert
thread.stop();
thread.join(timeoutMillis);
}
}

View File

@ -40,7 +40,12 @@
* number of aborted timed waits occur without a signal.
*/
import java.util.concurrent.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class PollMemoryLeak {
public static void main(String[] args) throws InterruptedException {

View File

@ -34,149 +34,126 @@
/*
* @test
* @bug 4486658
* @run main/timeout=3600 ProducerConsumerLoops
* @summary multiple producers and consumers using blocking queues
*/
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class ProducerConsumerLoops {
static final int CAPACITY = 100;
static final ExecutorService pool = Executors.newCachedThreadPool();
static boolean print = false;
static int producerSum;
static int consumerSum;
static synchronized void addProducerSum(int x) {
producerSum += x;
}
static synchronized void addConsumerSum(int x) {
consumerSum += x;
}
static synchronized void checkSum() {
if (producerSum != consumerSum)
throw new Error("CheckSum mismatch");
}
static ExecutorService pool;
public static void main(String[] args) throws Exception {
int maxPairs = 8;
final int maxPairs = (args.length > 0)
? Integer.parseInt(args[0])
: 5;
int iters = 10000;
if (args.length > 0)
maxPairs = Integer.parseInt(args[0]);
print = false;
System.out.println("Warmup...");
oneTest(1, 10000);
Thread.sleep(100);
oneTest(2, 10000);
Thread.sleep(100);
print = true;
pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) {
System.out.println("----------------------------------------");
System.out.println("Pairs: " + i);
oneTest(i, iters);
Thread.sleep(100);
// Adjust iterations to limit typical single runs to <= 10 ms;
// Notably, fair queues get fewer iters.
// Unbounded queues can legitimately OOME if iterations
// high enough, but we have a sufficiently low limit here.
run(new ArrayBlockingQueue<Integer>(100), i, 500);
run(new LinkedBlockingQueue<Integer>(100), i, 1000);
run(new LinkedBlockingDeque<Integer>(100), i, 1000);
run(new LinkedTransferQueue<Integer>(), i, 1000);
run(new PriorityBlockingQueue<Integer>(), i, 1000);
run(new SynchronousQueue<Integer>(), i, 400);
run(new SynchronousQueue<Integer>(true), i, 300);
run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
pool = null;
}
static void oneTest(int pairs, int iters) throws Exception {
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
oneRun(new PriorityBlockingQueue<Integer>(), pairs, iters);
oneRun(new SynchronousQueue<Integer>(), pairs, iters);
if (print)
System.out.println("fair implementations:");
oneRun(new SynchronousQueue<Integer>(true), pairs, iters);
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), pairs, iters);
static void run(BlockingQueue<Integer> queue, int pairs, int iters) throws Exception {
new ProducerConsumerLoops(queue, pairs, iters).run();
}
abstract static class Stage implements Runnable {
final int iters;
final BlockingQueue<Integer> queue;
final CyclicBarrier barrier;
Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
queue = q;
barrier = b;
this.iters = iters;
}
final BlockingQueue<Integer> queue;
final int pairs;
final int iters;
final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
final CyclicBarrier barrier;
final AtomicInteger checksum = new AtomicInteger(0);
Throwable fail;
ProducerConsumerLoops(BlockingQueue<Integer> queue, int pairs, int iters) {
this.queue = queue;
this.pairs = pairs;
this.iters = iters;
this.barrier = new CyclicBarrier(2 * pairs + 1, timer);
}
static class Producer extends Stage {
Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
public void run() {
try {
barrier.await();
int s = 0;
int l = hashCode();
for (int i = 0; i < iters; ++i) {
l = LoopHelpers.compute2(l);
queue.put(new Integer(l));
s += LoopHelpers.compute1(l);
}
addProducerSum(s);
barrier.await();
}
catch (Exception ie) {
ie.printStackTrace();
return;
}
}
}
static class Consumer extends Stage {
Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
public void run() {
try {
barrier.await();
int l = 0;
int s = 0;
for (int i = 0; i < iters; ++i) {
l = LoopHelpers.compute1(queue.take().intValue());
s += l;
}
addConsumerSum(s);
barrier.await();
}
catch (Exception ie) {
ie.printStackTrace();
return;
}
}
}
static void oneRun(BlockingQueue<Integer> q, int npairs, int iters) throws Exception {
if (print)
System.out.printf("%-18s", q.getClass().getSimpleName());
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer);
for (int i = 0; i < npairs; ++i) {
pool.execute(new Producer(q, barrier, iters));
pool.execute(new Consumer(q, barrier, iters));
void run() throws Exception {
for (int i = 0; i < pairs; i++) {
pool.execute(new Producer());
pool.execute(new Consumer());
}
barrier.await();
barrier.await();
long time = timer.getTime();
checkSum();
if (print)
System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * npairs)) + " ns per transfer");
System.out.printf("%s, pairs=%d: %d ms%n",
queue.getClass().getSimpleName(), pairs,
NANOSECONDS.toMillis(timer.getTime()));
if (checksum.get() != 0) throw new AssertionError("checksum mismatch");
if (fail != null) throw new AssertionError(fail);
}
abstract class CheckedRunnable implements Runnable {
abstract void realRun() throws Throwable;
public final void run() {
try {
realRun();
} catch (Throwable t) {
fail = t;
t.printStackTrace();
throw new AssertionError(t);
}
}
}
class Producer extends CheckedRunnable {
void realRun() throws Throwable {
barrier.await();
int s = 0;
int l = hashCode();
for (int i = 0; i < iters; i++) {
l = LoopHelpers.compute2(l);
queue.put(new Integer(l));
s += LoopHelpers.compute1(l);
}
checksum.getAndAdd(s);
barrier.await();
}
}
class Consumer extends CheckedRunnable {
void realRun() throws Throwable {
barrier.await();
int l = 0;
int s = 0;
for (int i = 0; i < iters; i++) {
l = LoopHelpers.compute1(queue.take().intValue());
s += l;
}
checksum.getAndAdd(-s);
barrier.await();
}
}
}

View File

@ -34,135 +34,126 @@
/*
* @test
* @bug 4486658
* @run main/timeout=600 SingleProducerMultipleConsumerLoops
* @summary check ordering for blocking queues with 1 producer and multiple consumers
*/
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class SingleProducerMultipleConsumerLoops {
static final int CAPACITY = 100;
static final ExecutorService pool = Executors.newCachedThreadPool();
static boolean print = false;
static ExecutorService pool;
public static void main(String[] args) throws Exception {
int maxConsumers = 5;
int iters = 10000;
if (args.length > 0)
maxConsumers = Integer.parseInt(args[0]);
print = false;
System.out.println("Warmup...");
oneTest(1, 10000);
Thread.sleep(100);
oneTest(2, 10000);
Thread.sleep(100);
print = true;
final int maxConsumers = (args.length > 0)
? Integer.parseInt(args[0])
: 5;
pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxConsumers; i += (i+1) >>> 1) {
System.out.println("----------------------------------------");
System.out.println("Consumers: " + i);
oneTest(i, iters);
Thread.sleep(100);
// Adjust iterations to limit typical single runs to <= 10 ms;
// Notably, fair queues get fewer iters.
// Unbounded queues can legitimately OOME if iterations
// high enough, but we have a sufficiently low limit here.
run(new ArrayBlockingQueue<Integer>(100), i, 1000);
run(new LinkedBlockingQueue<Integer>(100), i, 1000);
run(new LinkedBlockingDeque<Integer>(100), i, 1000);
run(new LinkedTransferQueue<Integer>(), i, 700);
run(new PriorityBlockingQueue<Integer>(), i, 1000);
run(new SynchronousQueue<Integer>(), i, 300);
run(new SynchronousQueue<Integer>(true), i, 200);
run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
pool = null;
}
static void oneTest(int consumers, int iters) throws Exception {
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), consumers, iters);
oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), consumers, iters);
oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), consumers, iters);
oneRun(new LinkedTransferQueue<Integer>(), consumers, iters);
oneRun(new PriorityBlockingQueue<Integer>(), consumers, iters);
oneRun(new SynchronousQueue<Integer>(), consumers, iters);
if (print)
System.out.println("fair implementations:");
oneRun(new SynchronousQueue<Integer>(true), consumers, iters);
oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), consumers, iters);
static void run(BlockingQueue<Integer> queue, int consumers, int iters) throws Exception {
new SingleProducerMultipleConsumerLoops(queue, consumers, iters).run();
}
abstract static class Stage implements Runnable {
final int iters;
final BlockingQueue<Integer> queue;
final CyclicBarrier barrier;
final BlockingQueue<Integer> queue;
final int consumers;
final int iters;
final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
final CyclicBarrier barrier;
Throwable fail;
SingleProducerMultipleConsumerLoops(BlockingQueue<Integer> queue, int consumers, int iters) {
this.queue = queue;
this.consumers = consumers;
this.iters = iters;
this.barrier = new CyclicBarrier(consumers + 2, timer);
}
void run() throws Exception {
pool.execute(new Producer());
for (int i = 0; i < consumers; i++) {
pool.execute(new Consumer());
}
barrier.await();
barrier.await();
System.out.printf("%s, consumers=%d: %d ms%n",
queue.getClass().getSimpleName(), consumers,
NANOSECONDS.toMillis(timer.getTime()));
if (fail != null) throw new AssertionError(fail);
}
abstract class CheckedRunnable implements Runnable {
abstract void realRun() throws Throwable;
public final void run() {
try {
realRun();
} catch (Throwable t) {
fail = t;
t.printStackTrace();
throw new AssertionError(t);
}
}
}
class Producer extends CheckedRunnable {
volatile int result;
Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
queue = q;
barrier = b;
this.iters = iters;
void realRun() throws Throwable {
barrier.await();
for (int i = 0; i < iters * consumers; i++) {
queue.put(new Integer(i));
}
barrier.await();
result = 432;
}
}
static class Producer extends Stage {
Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
public void run() {
try {
barrier.await();
for (int i = 0; i < iters; ++i) {
queue.put(new Integer(i));
}
barrier.await();
result = 432;
}
catch (Exception ie) {
ie.printStackTrace();
return;
class Consumer extends CheckedRunnable {
volatile int result;
void realRun() throws Throwable {
barrier.await();
int l = 0;
int s = 0;
int last = -1;
for (int i = 0; i < iters; i++) {
Integer item = queue.take();
int v = item.intValue();
if (v < last)
throw new Error("Out-of-Order transfer");
last = v;
l = LoopHelpers.compute1(v);
s += l;
}
barrier.await();
result = s;
}
}
static class Consumer extends Stage {
Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
super(q, b, iters);
}
public void run() {
try {
barrier.await();
int l = 0;
int s = 0;
int last = -1;
for (int i = 0; i < iters; ++i) {
Integer item = queue.take();
int v = item.intValue();
if (v < last)
throw new Error("Out-of-Order transfer");
last = v;
l = LoopHelpers.compute1(v);
s += l;
}
barrier.await();
result = s;
}
catch (Exception ie) {
ie.printStackTrace();
return;
}
}
}
static void oneRun(BlockingQueue<Integer> q, int nconsumers, int iters) throws Exception {
if (print)
System.out.printf("%-18s", q.getClass().getSimpleName());
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(nconsumers + 2, timer);
pool.execute(new Producer(q, barrier, iters * nconsumers));
for (int i = 0; i < nconsumers; ++i) {
pool.execute(new Consumer(q, barrier, iters));
}
barrier.await();
barrier.await();
long time = timer.getTime();
if (print)
System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nconsumers)) + " ns per transfer");
}
}

View File

@ -40,17 +40,19 @@
* @author Chris Hegarty
*/
import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import static java.util.concurrent.ForkJoinPool.commonPool;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.reflect.Array;
import java.util.concurrent.Phaser;
import static java.util.concurrent.TimeUnit.*;
import java.util.concurrent.CompletableFuture;
import static java.util.concurrent.CompletableFuture.*;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static java.util.concurrent.ForkJoinPool.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Basic {
@ -112,7 +114,7 @@ public class Basic {
test(executor);
} finally {
executor.shutdown();
executor.awaitTermination(30, SECONDS);
executor.awaitTermination(30L, SECONDS);
}
}

View File

@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.concurrent.atomic.AtomicLong;
/**
* Misc utilities in JSR166 performance tests
*/
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@ -74,28 +72,6 @@ class LoopHelpers {
return x;
}
/**
* An actually useful random number generator, but unsynchronized.
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
public void setSeed(long s) {
seed = s;
}
public int next() {
long nextseed = (seed * multiplier + addend) & mask;
seed = nextseed;
return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
}
}
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;

View File

@ -38,8 +38,20 @@
* @summary Times and checks basic map operations
*/
import java.util.*;
import java.io.*;
import java.io.Serializable;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SplittableRandom;
public class MapCheck {
@ -599,12 +611,11 @@ public class MapCheck {
Stats(double t) { least = t; }
}
static Random rng = new Random();
static void shuffle(Object[] keys) {
SplittableRandom rnd = new SplittableRandom();
int size = keys.length;
for (int i=size; i>1; i--) {
int r = rng.nextInt(i);
int r = rnd.nextInt(i);
Object t = keys[i-1];
keys[i-1] = keys[r];
keys[r] = t;

View File

@ -44,15 +44,22 @@
* parsing from command line.)
*/
import java.util.*;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.List;
import java.util.Map;
import java.util.SplittableRandom;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MapLoops {
static int nkeys = 10000;
static int nkeys = 1000; // 10_000
static int pinsert = 60;
static int premove = 2;
static int maxThreads = 100;
static int nops = 100000;
static int nops = 10000; // 100_000
static int removesPerMaxRandom;
static int insertsPerMaxRandom;
@ -104,7 +111,6 @@ public class MapLoops {
int k = 1;
int warmups = 2;
for (int i = 1; i <= maxThreads;) {
Thread.sleep(100);
test(i, nkeys, mapClass);
if (warmups > 0)
--warmups;
@ -120,7 +126,7 @@ public class MapLoops {
i = k;
}
pool.shutdown();
if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
if (! throwables.isEmpty())
@ -129,17 +135,17 @@ public class MapLoops {
}
static Integer[] makeKeys(int n) {
LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
SplittableRandom rnd = new SplittableRandom();
Integer[] key = new Integer[n];
for (int i = 0; i < key.length; ++i)
key[i] = new Integer(rng.next());
key[i] = new Integer(rnd.nextInt());
return key;
}
static void shuffleKeys(Integer[] key) {
Random rng = new Random();
SplittableRandom rnd = new SplittableRandom();
for (int i = key.length; i > 1; --i) {
int j = rng.nextInt(i);
int j = rnd.nextInt(i);
Integer tmp = key[j];
key[j] = key[i-1];
key[i-1] = tmp;
@ -155,8 +161,9 @@ public class MapLoops {
// map.put(key[j], key[j]);
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(i+1, timer);
SplittableRandom rnd = new SplittableRandom();
for (int t = 0; t < i; ++t)
pool.execute(new Runner(map, key, barrier));
pool.execute(new Runner(map, key, barrier, rnd.split()));
barrier.await();
barrier.await();
long time = timer.getTime();
@ -170,21 +177,25 @@ public class MapLoops {
static class Runner implements Runnable {
final Map<Integer,Integer> map;
final Integer[] key;
final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
final CyclicBarrier barrier;
final SplittableRandom rnd;
int position;
int total;
Runner(Map<Integer,Integer> map, Integer[] key, CyclicBarrier barrier) {
Runner(Map<Integer,Integer> map,
Integer[] key,
CyclicBarrier barrier,
SplittableRandom rnd) {
this.map = map;
this.key = key;
this.barrier = barrier;
this.rnd = rnd;
position = key.length / 2;
}
int step() {
// random-walk around key positions, bunching accesses
int r = rng.next();
int r = rnd.nextInt(Integer.MAX_VALUE);
position += (r & 7) - 3;
while (position >= key.length) position -= key.length;
while (position < 0) position += key.length;

View File

@ -27,8 +27,11 @@
* @summary Reasonable things should happen if mutating while iterating.
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
public class ConcurrentModification {
static volatile int passed = 0, failed = 0;

View File

@ -38,9 +38,25 @@
* @summary Checks that a set of threads can repeatedly get and modify items
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class ConcurrentQueueLoops {
ExecutorService pool;
@ -99,7 +115,7 @@ public class ConcurrentQueueLoops {
oneRun(i, items, q);
}
pool.shutdown();
check(pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS));
check(pool.awaitTermination(60L, SECONDS));
}
class Stage implements Callable<Integer> {

View File

@ -31,15 +31,28 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.*;
import java.util.concurrent.*;
/*
* @test
* @bug 6805775 6815766
* @summary Check weak consistency of concurrent queue iterators
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
@SuppressWarnings({"unchecked", "rawtypes"})
public class IteratorWeakConsistency {
final Random rnd = new Random();

View File

@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.concurrent.atomic.AtomicLong;
/**
* Misc utilities in JSR166 performance tests
*/
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@ -74,28 +72,6 @@ class LoopHelpers {
return x;
}
/**
* An actually useful random number generator, but unsynchronized.
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
public void setSeed(long s) {
seed = s;
}
public int next() {
long nextseed = (seed * multiplier + addend) & mask;
seed = nextseed;
return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
}
}
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;

View File

@ -29,10 +29,21 @@
* @author Martin Buchholz
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import static java.util.concurrent.TimeUnit.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.Arrays;
import java.util.Queue;
import java.util.SplittableRandom;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadLocalRandom;
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class OfferRemoveLoops {
@ -61,10 +72,6 @@ public class OfferRemoveLoops {
testQueue(new LinkedTransferQueue());
}
Random getRandom() {
return ThreadLocalRandom.current();
}
void testQueue(final Queue q) throws Throwable {
System.err.println(q.getClass().getSimpleName());
final long testDurationNanos = testDurationMillis * 1000L * 1000L;
@ -73,13 +80,17 @@ public class OfferRemoveLoops {
final int maxChunkSize = 1042;
final int maxQueueSize = 10 * maxChunkSize;
final CountDownLatch done = new CountDownLatch(3);
final SplittableRandom rnd = new SplittableRandom();
/** Poor man's bounded buffer; prevents unbounded queue expansion. */
final Semaphore offers = new Semaphore(maxQueueSize);
abstract class CheckedThread extends Thread {
CheckedThread(String name) {
final SplittableRandom rnd;
CheckedThread(String name, SplittableRandom rnd) {
super(name);
this.rnd = rnd;
setDaemon(true);
start();
}
@ -97,9 +108,9 @@ public class OfferRemoveLoops {
}
}
Thread offerer = new CheckedThread("offerer") {
Thread offerer = new CheckedThread("offerer", rnd.split()) {
protected void realRun() throws InterruptedException {
final int chunkSize = getRandom().nextInt(maxChunkSize) + 20;
final int chunkSize = rnd.nextInt(maxChunkSize) + 20;
long c = 0;
while (! quittingTime()) {
if (q.offer(Long.valueOf(c))) {
@ -113,9 +124,9 @@ public class OfferRemoveLoops {
done.countDown();
}};
Thread remover = new CheckedThread("remover") {
Thread remover = new CheckedThread("remover", rnd.split()) {
protected void realRun() {
final int chunkSize = getRandom().nextInt(maxChunkSize) + 20;
final int chunkSize = rnd.nextInt(maxChunkSize) + 20;
long c = 0;
while (! quittingTime()) {
if (q.remove(Long.valueOf(c))) {
@ -131,9 +142,8 @@ public class OfferRemoveLoops {
done.countDown();
}};
Thread scanner = new CheckedThread("scanner") {
Thread scanner = new CheckedThread("scanner", rnd.split()) {
protected void realRun() {
final Random rnd = getRandom();
while (! quittingTime()) {
switch (rnd.nextInt(3)) {
case 0: checkNotContainsNull(q); break;

View File

@ -26,6 +26,7 @@
* @bug 8011645
* @summary CopyOnWriteArrayList.COWSubList.subList does not validate range properly
*/
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

View File

@ -28,8 +28,10 @@
* @author Martin Buchholz
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class EqualsRace {
private static void realMain(String[] args) throws Throwable {

View File

@ -28,8 +28,10 @@
* @author Martin Buchholz
*/
import java.util.*;
import java.util.concurrent.*;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
public class RacingCows {
private static void realMain(String[] args) throws Throwable {

View File

@ -28,7 +28,8 @@
* @author Seetharam Avadhanam, Martin Buchholz
*/
import java.util.concurrent.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
interface AwaiterFactory {

Some files were not shown because too many files have changed in this diff Show More