mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
Merge
This commit is contained in:
commit
d77f96b0b2
684 changed files with 47732 additions and 20486 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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™ Language Specification</cite></a>:
|
||||
* <ul>
|
||||
|
|
|
@ -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™ Language Specification</cite></a>.
|
||||
* Methods successfully unlocking in write mode have the same memory
|
||||
* synchronization effects as an <em>Unlock</em> action. In optimistic
|
||||
|
|
|
@ -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™ Language Specification</cite></a> defines the
|
||||
* <i>happens-before</i> relation on memory operations such as reads and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue