Merge
This commit is contained in:
commit
e528753f4d
@ -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)
|
||||
|
55
jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk
Normal file
55
jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk
Normal 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
|
@ -33,4 +33,3 @@ include TextFileProcessing.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
# We need the tools.
|
||||
include Tools.gmk
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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/%, \
|
||||
|
@ -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, \
|
||||
))
|
||||
|
||||
|
@ -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, \
|
||||
))
|
||||
|
@ -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, \
|
||||
))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -448,9 +448,7 @@ public final class Long extends Number implements Comparable<Long> {
|
||||
* @return a string representation of the argument in base 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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}
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
101
jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java
Normal file
101
jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
76
jdk/src/java.sql/share/classes/java/sql/ShardingKey.java
Normal file
76
jdk/src/java.sql/share/classes/java/sql/ShardingKey.java
Normal 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 {
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
};
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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");
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -0,0 +1 @@
|
||||
sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 {
|
||||
|
85
jdk/test/java/lang/Integer/ToString.java
Normal file
85
jdk/test/java/lang/Integer/ToString.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
85
jdk/test/java/lang/Long/ToString.java
Normal file
85
jdk/test/java/lang/Long/ToString.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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},};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
*/
|
||||
/*
|
||||
@test
|
||||
@ignore 6876961
|
||||
@summary test that ResourceBundle.getBundle can be called recursively
|
||||
@build Test4300693RB
|
||||
@run main Test4300693
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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});
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @bug 8011645
|
||||
* @summary CopyOnWriteArrayList.COWSubList.subList does not validate range properly
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user