This commit is contained in:
Henry Jen 2018-12-13 11:47:35 -08:00
commit d77f96b0b2
684 changed files with 47732 additions and 20486 deletions

View file

@ -681,11 +681,12 @@ class Character implements java.io.Serializable, Comparable<Character> {
*/
public static final class UnicodeBlock extends Subset {
/**
* 649 - the expected number of entities
* 667 - the expected number of entities
* 0.75 - the default load factor of HashMap
*/
private static final int NUM_ENTITIES = 667;
private static Map<String, UnicodeBlock> map =
new HashMap<>((int)(649 / 0.75f + 1.0f));
new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f));
/**
* Creates a UnicodeBlock with the given identifier name.
@ -9084,7 +9085,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
* @since 1.5
*/
public static boolean isLowerCase(int codePoint) {
return getType(codePoint) == Character.LOWERCASE_LETTER ||
return CharacterData.of(codePoint).isLowerCase(codePoint) ||
CharacterData.of(codePoint).isOtherLowercase(codePoint);
}
@ -9150,7 +9151,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
* @since 1.5
*/
public static boolean isUpperCase(int codePoint) {
return getType(codePoint) == Character.UPPERCASE_LETTER ||
return CharacterData.of(codePoint).isUpperCase(codePoint) ||
CharacterData.of(codePoint).isOtherUppercase(codePoint);
}
@ -9301,7 +9302,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
* @since 1.5
*/
public static boolean isDigit(int codePoint) {
return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
return CharacterData.of(codePoint).isDigit(codePoint);
}
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2018, 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
@ -28,6 +28,9 @@ package java.lang;
abstract class CharacterData {
abstract int getProperties(int ch);
abstract int getType(int ch);
abstract boolean isDigit(int ch);
abstract boolean isLowerCase(int ch);
abstract boolean isUpperCase(int ch);
abstract boolean isWhitespace(int ch);
abstract boolean isMirrored(int ch);
abstract boolean isJavaIdentifierStart(int ch);

View file

@ -94,12 +94,10 @@ public class Object {
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined
* by class {@code Object} does return distinct integers for
* distinct objects. (The hashCode may or may not be implemented
* as some function of an object's memory address at some point
* in time.)
*
* @implSpec
* As far as is reasonably practical, the {@code hashCode} method defined
* by class {@code Object} returns distinct integers for distinct objects.
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)

View file

@ -801,8 +801,9 @@ public final class System {
}
if (props == null) {
props = SystemProps.initProperties();
VersionProps.init(props);
Map<String, String> tempProps = SystemProps.initProperties();
VersionProps.init(tempProps);
props = createProperties(tempProps);
}
System.props = props;
}
@ -1959,18 +1960,42 @@ public final class System {
}
}
/**
* Create the Properties object from a map - masking out system properties
* that are not intended for public access.
*/
private static Properties createProperties(Map<String, String> initialProps) {
Properties properties = new Properties(initialProps.size());
for (var entry : initialProps.entrySet()) {
String prop = entry.getKey();
switch (prop) {
// Do not add private system properties to the Properties
case "sun.nio.MaxDirectMemorySize":
case "sun.nio.PageAlignDirectMemory":
// used by java.lang.Integer.IntegerCache
case "java.lang.Integer.IntegerCache.high":
// used by sun.launcher.LauncherHelper
case "sun.java.launcher.diag":
// used by jdk.internal.loader.ClassLoaders
case "jdk.boot.class.path.append":
break;
default:
properties.put(prop, entry.getValue());
}
}
return properties;
}
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initPhase1() {
// VM might invoke JNU_NewStringPlatform() to set those encoding
// sensitive properties (user.home, user.name, boot.class.path, etc.)
// during "props" initialization.
// The charset is initialized in System.c and does not depend on the Properties.
props = SystemProps.initProperties();
VersionProps.init(props);
StaticProperty.javaHome(); // Load StaticProperty to cache the property values
Map<String, String> tempProps = SystemProps.initProperties();
VersionProps.init(tempProps);
// There are certain system configurations that may be controlled by
// VM options such as the maximum amount of direct memory and
@ -1978,15 +2003,14 @@ public final class System {
// of autoboxing. Typically, the library will obtain these values
// from the properties set by the VM. If the properties are for
// internal implementation use only, these properties should be
// removed from the system properties.
//
// See java.lang.Integer.IntegerCache and the
// VM.saveAndRemoveProperties method for example.
// masked from the system properties.
//
// Save a private copy of the system properties object that
// can only be accessed by the internal implementation. Remove
// certain system properties that are not intended for public access.
VM.saveAndRemoveProperties(props);
// can only be accessed by the internal implementation.
VM.saveProperties(tempProps);
props = createProperties(tempProps);
StaticProperty.javaHome(); // Load StaticProperty to cache the property values
lineSeparator = props.getProperty("line.separator");

View file

@ -28,8 +28,8 @@ package java.lang;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
class VersionProps {
@ -88,25 +88,25 @@ class VersionProps {
/**
* Initialize system properties using build provided values.
*
* @param props Properties instance in which to insert the properties
* @param props Map instance in which to insert the properties
*/
public static void init(Properties props) {
props.setProperty("java.version", java_version);
props.setProperty("java.version.date", java_version_date);
props.setProperty("java.runtime.version", java_runtime_version);
props.setProperty("java.runtime.name", java_runtime_name);
public static void init(Map<String, String> props) {
props.put("java.version", java_version);
props.put("java.version.date", java_version_date);
props.put("java.runtime.version", java_runtime_version);
props.put("java.runtime.name", java_runtime_name);
if (VENDOR_VERSION_STRING.length() > 0)
props.setProperty("java.vendor.version", VENDOR_VERSION_STRING);
props.put("java.vendor.version", VENDOR_VERSION_STRING);
props.setProperty("java.class.version", CLASSFILE_MAJOR_MINOR);
props.put("java.class.version", CLASSFILE_MAJOR_MINOR);
props.setProperty("java.specification.version", VERSION_SPECIFICATION);
props.setProperty("java.specification.name", "Java Platform API Specification");
props.setProperty("java.specification.vendor", "Oracle Corporation");
props.put("java.specification.version", VERSION_SPECIFICATION);
props.put("java.specification.name", "Java Platform API Specification");
props.put("java.specification.vendor", "Oracle Corporation");
props.setProperty("java.vendor", VENDOR);
props.setProperty("java.vendor.url", VENDOR_URL);
props.setProperty("java.vendor.url.bug", VENDOR_URL_BUG);
props.put("java.vendor", VENDOR);
props.put("java.vendor.url", VENDOR_URL);
props.put("java.vendor.url.bug", VENDOR_URL_BUG);
}
private static int parseVersionNumber(String version, int prevIndex, int index) {

View file

@ -25,6 +25,7 @@
package java.net;
import java.io.File;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@ -36,6 +37,7 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.nio.file.Path;
import java.text.Normalizer;
import jdk.internal.access.JavaNetUriAccess;
import jdk.internal.access.SharedSecrets;
@ -458,6 +460,27 @@ import java.lang.NullPointerException; // for javadoc
* resolution as well as the network I/O operations of looking up the host and
* opening a connection to the specified resource.
*
* @apiNote
*
* Applications working with file paths and file URIs should take great
* care to use the appropriate methods to convert between the two.
* The {@link Path#of(URI)} factory method and the {@link File#File(URI)}
* constructor can be used to create {@link Path} or {@link File}
* objects from a file URI. {@link Path#toUri()} and {@link File#toURI()}
* can be used to create a {@link URI} from a file path.
* Applications should never try to {@linkplain
* #URI(String, String, String, int, String, String, String)
* construct}, {@linkplain #URI(String) parse}, or
* {@linkplain #resolve(String) resolve} a {@code URI}
* from the direct string representation of a {@code File} or {@code Path}
* instance.
* <p>
* Some components of a URL or URI, such as <i>userinfo</i>, may
* be abused to construct misleading URLs or URIs. Applications
* that deal with URLs or URIs should take into account
* the recommendations advised in <a
* href="https://tools.ietf.org/html/rfc3986#section-7">RFC3986,
* Section 7, Security Considerations</a>.
*
* @author Mark Reinhold
* @since 1.4

View file

@ -25,9 +25,11 @@
package java.net;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.spi.URLStreamHandlerProvider;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable;
@ -145,6 +147,27 @@ import sun.security.action.GetPropertyAction;
* used, but only for HTML form encoding, which is not the same
* as the encoding scheme defined in RFC2396.
*
* @apiNote
*
* Applications working with file paths and file URIs should take great
* care to use the appropriate methods to convert between the two.
* The {@link Path#of(URI)} factory method and the {@link File#File(URI)}
* constructor can be used to create {@link Path} or {@link File}
* objects from a file URI. {@link Path#toUri()} and {@link File#toURI()}
* can be used to create a {@link URI} from a file path, which can be
* converted to URL using {@link URI#toURL()}.
* Applications should never try to {@linkplain #URL(String, String, String)
* construct} or {@linkplain #URL(String) parse} a {@code URL}
* from the direct string representation of a {@code File} or {@code Path}
* instance.
* <p>
* Some components of a URL or URI, such as <i>userinfo</i>, may
* be abused to construct misleading URLs or URIs. Applications
* that deal with URLs or URIs should take into account
* the recommendations advised in <a
* href="https://tools.ietf.org/html/rfc3986#section-7">RFC3986,
* Section 7, Security Considerations</a>.
*
* @author James Gosling
* @since 1.0
*/

View file

@ -314,14 +314,7 @@ public class KeyStore {
/**
* Gets the name of the protection algorithm.
* If none was set then the keystore provider will use its default
* protection algorithm. The name of the default protection algorithm
* for a given keystore type is set using the
* {@code 'keystore.<type>.keyProtectionAlgorithm'} security property.
* For example, the
* {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the
* name of the default key protection algorithm used for PKCS12
* keystores. If the security property is not set, an
* implementation-specific algorithm will be used.
* protection algorithm.
*
* @return the algorithm name, or {@code null} if none was set
*
@ -1813,8 +1806,8 @@ public class KeyStore {
}
}
throw new KeyStoreException("This keystore does not support probing "
+ "and must be loaded with a specified type");
throw new KeyStoreException("Unrecognized keystore format. "
+ "Please load it with a specified type");
}
/**

View file

@ -33,6 +33,7 @@ import java.lang.reflect.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.concurrent.ConcurrentHashMap;
/**
* This class represents a "provider" for the
@ -225,6 +226,7 @@ public abstract class Provider extends Properties {
this.version = version;
this.versionStr = Double.toString(version);
this.info = info;
this.serviceMap = new ConcurrentHashMap<>();
putId();
initialized = true;
}
@ -262,6 +264,7 @@ public abstract class Provider extends Properties {
this.versionStr = versionStr;
this.version = parseVersionStr(versionStr);
this.info = info;
this.serviceMap = new ConcurrentHashMap<>();
putId();
initialized = true;
}
@ -852,10 +855,7 @@ public abstract class Provider extends Properties {
// legacy properties changed since last call to any services method?
private transient boolean legacyChanged;
// serviceMap changed since last call to getServices()
private transient boolean servicesChanged;
// Map<String,String>
private transient Map<String,String> legacyStrings;
private volatile transient boolean servicesChanged;
// Map<ServiceKey,Service>
// used for services added via putService(), initialized on demand
@ -905,22 +905,18 @@ public abstract class Provider extends Properties {
// otherwise, set version based on versionStr
this.version = parseVersionStr(this.versionStr);
}
this.serviceMap = new ConcurrentHashMap<>();
implClear();
initialized = true;
putAll(copy);
}
private boolean checkLegacy(Object key) {
private static boolean isProviderInfo(Object key) {
String keyString = (String)key;
if (keyString.startsWith("Provider.")) {
return false;
return true;
}
legacyChanged = true;
if (legacyStrings == null) {
legacyStrings = new LinkedHashMap<>();
}
return true;
return false;
}
/**
@ -936,20 +932,20 @@ public abstract class Provider extends Properties {
private Object implRemove(Object key) {
if (key instanceof String) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.remove((String)key);
legacyChanged = true;
}
return super.remove(key);
}
private boolean implRemove(Object key, Object value) {
if (key instanceof String && value instanceof String) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return false;
}
legacyStrings.remove((String)key, value);
legacyChanged = true;
}
return super.remove(key, value);
}
@ -957,21 +953,20 @@ public abstract class Provider extends Properties {
private boolean implReplace(Object key, Object oldValue, Object newValue) {
if ((key instanceof String) && (oldValue instanceof String) &&
(newValue instanceof String)) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return false;
}
legacyStrings.replace((String)key, (String)oldValue,
(String)newValue);
legacyChanged = true;
}
return super.replace(key, oldValue, newValue);
}
private Object implReplace(Object key, Object value) {
if ((key instanceof String) && (value instanceof String)) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.replace((String)key, (String)value);
legacyChanged = true;
}
return super.replace(key, value);
}
@ -980,12 +975,6 @@ public abstract class Provider extends Properties {
private void implReplaceAll(BiFunction<? super Object, ? super Object,
? extends Object> function) {
legacyChanged = true;
if (legacyStrings == null) {
legacyStrings = new LinkedHashMap<>();
} else {
legacyStrings.replaceAll((BiFunction<? super String, ? super String,
? extends String>) function);
}
super.replaceAll(function);
}
@ -993,11 +982,10 @@ public abstract class Provider extends Properties {
private Object implMerge(Object key, Object value, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
if ((key instanceof String) && (value instanceof String)) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.merge((String)key, (String)value,
(BiFunction<? super String, ? super String, ? extends String>) remappingFunction);
legacyChanged = true;
}
return super.merge(key, value, remappingFunction);
}
@ -1006,11 +994,10 @@ public abstract class Provider extends Properties {
private Object implCompute(Object key, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
if (key instanceof String) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.compute((String) key,
(BiFunction<? super String,? super String, ? extends String>) remappingFunction);
legacyChanged = true;
}
return super.compute(key, remappingFunction);
}
@ -1019,11 +1006,10 @@ public abstract class Provider extends Properties {
private Object implComputeIfAbsent(Object key, Function<? super Object,
? extends Object> mappingFunction) {
if (key instanceof String) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.computeIfAbsent((String) key,
(Function<? super String, ? extends String>) mappingFunction);
legacyChanged = true;
}
return super.computeIfAbsent(key, mappingFunction);
}
@ -1032,45 +1018,39 @@ public abstract class Provider extends Properties {
private Object implComputeIfPresent(Object key, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
if (key instanceof String) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.computeIfPresent((String) key,
(BiFunction<? super String, ? super String, ? extends String>) remappingFunction);
legacyChanged = true;
}
return super.computeIfPresent(key, remappingFunction);
}
private Object implPut(Object key, Object value) {
if ((key instanceof String) && (value instanceof String)) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.put((String)key, (String)value);
legacyChanged = true;
}
return super.put(key, value);
}
private Object implPutIfAbsent(Object key, Object value) {
if ((key instanceof String) && (value instanceof String)) {
if (!checkLegacy(key)) {
if (isProviderInfo(key)) {
return null;
}
legacyStrings.putIfAbsent((String)key, (String)value);
legacyChanged = true;
}
return super.putIfAbsent(key, value);
}
private void implClear() {
if (legacyStrings != null) {
legacyStrings.clear();
}
if (legacyMap != null) {
legacyMap.clear();
}
if (serviceMap != null) {
serviceMap.clear();
}
serviceMap.clear();
legacyChanged = false;
servicesChanged = false;
serviceSet = null;
@ -1090,13 +1070,13 @@ public abstract class Provider extends Properties {
this.algorithm = intern ? algorithm.intern() : algorithm;
}
public int hashCode() {
return type.hashCode() + algorithm.hashCode();
return Objects.hash(type, algorithm);
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ServiceKey == false) {
if (!(obj instanceof ServiceKey)) {
return false;
}
ServiceKey other = (ServiceKey)obj;
@ -1113,16 +1093,16 @@ public abstract class Provider extends Properties {
* service objects.
*/
private void ensureLegacyParsed() {
if ((legacyChanged == false) || (legacyStrings == null)) {
if (legacyChanged == false) {
return;
}
serviceSet = null;
if (legacyMap == null) {
legacyMap = new LinkedHashMap<>();
legacyMap = new ConcurrentHashMap<>();
} else {
legacyMap.clear();
}
for (Map.Entry<String,String> entry : legacyStrings.entrySet()) {
for (Map.Entry<?,?> entry : super.entrySet()) {
parseLegacyPut(entry.getKey(), entry.getValue());
}
removeInvalidServices(legacyMap);
@ -1161,7 +1141,15 @@ public abstract class Provider extends Properties {
private static final String ALIAS_PREFIX_LOWER = "alg.alias.";
private static final int ALIAS_LENGTH = ALIAS_PREFIX.length();
private void parseLegacyPut(String name, String value) {
private void parseLegacyPut(Object k, Object v) {
if (!(k instanceof String) || !(v instanceof String)) {
return;
}
String name = (String) k;
String value = (String) v;
if (isProviderInfo(name)) {
return;
}
if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) {
// e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1");
// aliasKey ~ MessageDigest.SHA
@ -1248,22 +1236,28 @@ public abstract class Provider extends Properties {
*
* @since 1.5
*/
public synchronized Service getService(String type, String algorithm) {
public Service getService(String type, String algorithm) {
checkInitialized();
// avoid allocating a new key object if possible
// avoid allocating a new ServiceKey object if possible
ServiceKey key = previousKey;
if (key.matches(type, algorithm) == false) {
key = new ServiceKey(type, algorithm, false);
previousKey = key;
}
if (serviceMap != null) {
Service service = serviceMap.get(key);
if (service != null) {
return service;
if (!serviceMap.isEmpty()) {
Service s = serviceMap.get(key);
if (s != null) {
return s;
}
}
ensureLegacyParsed();
return (legacyMap != null) ? legacyMap.get(key) : null;
synchronized (this) {
ensureLegacyParsed();
}
if (legacyMap != null && !legacyMap.isEmpty()) {
return legacyMap.get(key);
}
return null;
}
// ServiceKey from previous getService() call
@ -1292,10 +1286,10 @@ public abstract class Provider extends Properties {
if (serviceSet == null) {
ensureLegacyParsed();
Set<Service> set = new LinkedHashSet<>();
if (serviceMap != null) {
if (!serviceMap.isEmpty()) {
set.addAll(serviceMap.values());
}
if (legacyMap != null) {
if (legacyMap != null && !legacyMap.isEmpty()) {
set.addAll(legacyMap.values());
}
serviceSet = Collections.unmodifiableSet(set);
@ -1333,7 +1327,7 @@ public abstract class Provider extends Properties {
*
* @since 1.5
*/
protected synchronized void putService(Service s) {
protected void putService(Service s) {
check("putProviderProperty." + name);
if (debug != null) {
debug.println(name + ".putService(): " + s);
@ -1345,20 +1339,18 @@ public abstract class Provider extends Properties {
throw new IllegalArgumentException
("service.getProvider() must match this Provider object");
}
if (serviceMap == null) {
serviceMap = new LinkedHashMap<>();
}
servicesChanged = true;
String type = s.getType();
String algorithm = s.getAlgorithm();
ServiceKey key = new ServiceKey(type, algorithm, true);
// remove existing service
implRemoveService(serviceMap.get(key));
serviceMap.put(key, s);
for (String alias : s.getAliases()) {
serviceMap.put(new ServiceKey(type, alias, true), s);
}
putPropertyStrings(s);
servicesChanged = true;
synchronized (this) {
putPropertyStrings(s);
}
}
/**
@ -1425,7 +1417,7 @@ public abstract class Provider extends Properties {
*
* @since 1.5
*/
protected synchronized void removeService(Service s) {
protected void removeService(Service s) {
check("removeProviderProperty." + name);
if (debug != null) {
debug.println(name + ".removeService(): " + s);
@ -1437,7 +1429,7 @@ public abstract class Provider extends Properties {
}
private void implRemoveService(Service s) {
if ((s == null) || (serviceMap == null)) {
if ((s == null) || serviceMap.isEmpty()) {
return;
}
String type = s.getType();
@ -1452,7 +1444,9 @@ public abstract class Provider extends Properties {
for (String alias : s.getAliases()) {
serviceMap.remove(new ServiceKey(type, alias, false));
}
removePropertyStrings(s);
synchronized (this) {
removePropertyStrings(s);
}
}
// Wrapped String that behaves in a case insensitive way for equals/hashCode

View file

@ -80,7 +80,7 @@ import java.util.stream.StreamSupport;
* in security-sensitive applications. Additionally,
* default-constructed instances do not use a cryptographically random
* seed unless the {@linkplain System#getProperty system property}
* {@code java.util.secureRandomSeed} is set to {@code true}.
* {@systemProperty java.util.secureRandomSeed} is set to {@code true}.
*
* @author Guy Steele
* @author Doug Lea

View file

@ -2334,17 +2334,15 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
Node<K,V>[] tab, nt; int n, sc;
while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
(n = tab.length) < MAXIMUM_CAPACITY) {
int rs = resizeStamp(n);
int rs = resizeStamp(n) << RESIZE_STAMP_SHIFT;
if (sc < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
transferIndex <= 0)
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
(nt = nextTable) == null || transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSetInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
transfer(tab, null);
s = sumCount();
}
@ -2358,11 +2356,11 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
Node<K,V>[] nextTab; int sc;
if (tab != null && (f instanceof ForwardingNode) &&
(nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
int rs = resizeStamp(tab.length);
int rs = resizeStamp(tab.length) << RESIZE_STAMP_SHIFT;
while (nextTab == nextTable && table == tab &&
(sc = sizeCtl) < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || transferIndex <= 0)
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) {
transfer(tab, nextTab);

View file

@ -136,17 +136,17 @@ import java.util.concurrent.locks.LockSupport;
* <p>The parameters used to construct the common pool may be controlled by
* setting the following {@linkplain System#getProperty system properties}:
* <ul>
* <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.parallelism}
* - the parallelism level, a non-negative integer
* <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.threadFactory}
* - the class name of a {@link ForkJoinWorkerThreadFactory}.
* The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
* is used to load this class.
* <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.exceptionHandler}
* - the class name of a {@link UncaughtExceptionHandler}.
* The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
* is used to load this class.
* <li>{@code java.util.concurrent.ForkJoinPool.common.maximumSpares}
* <li>{@systemProperty java.util.concurrent.ForkJoinPool.common.maximumSpares}
* - the maximum number of allowed extra threads to maintain target
* parallelism (default 256).
* </ul>

View file

@ -122,7 +122,7 @@ import java.util.concurrent.TimeUnit;
* <p>All {@code Lock} implementations <em>must</em> enforce the same
* memory synchronization semantics as provided by the built-in monitor
* lock, as described in
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4">
* Chapter 17 of
* <cite>The Java&trade; Language Specification</cite></a>:
* <ul>

View file

@ -133,7 +133,7 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
* <p><b>Memory Synchronization.</b> Methods with the effect of
* successfully locking in any mode have the same memory
* synchronization effects as a <em>Lock</em> action described in
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4">
* Chapter 17 of <cite>The Java&trade; Language Specification</cite></a>.
* Methods successfully unlocking in write mode have the same memory
* synchronization effects as an <em>Unlock</em> action. In optimistic

View file

@ -226,7 +226,7 @@
*
* <h2 id="MemoryVisibility">Memory Consistency Properties</h2>
*
* <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5">
* <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.4.5">
* Chapter 17 of
* <cite>The Java&trade; Language Specification</cite></a> defines the
* <i>happens-before</i> relation on memory operations such as reads and