mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
Merge
This commit is contained in:
commit
eed5d34c26
235 changed files with 7673 additions and 2642 deletions
|
@ -2160,10 +2160,12 @@ public abstract class ClassLoader {
|
|||
* if a package of the given {@code name} is already
|
||||
* defined by this class loader
|
||||
*
|
||||
*
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* The JAR File Specification: Package Sealing</a>
|
||||
*/
|
||||
|
@ -2186,17 +2188,19 @@ public abstract class ClassLoader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Package} of the given <a href="#name">name</a> that has been
|
||||
* defined by this class loader.
|
||||
* Returns a {@code Package} of the given <a href="#name">name</a> that
|
||||
* has been defined by this class loader.
|
||||
*
|
||||
* @param name The <a href="#name">package name</a>
|
||||
*
|
||||
* @return The {@code Package} of the given name defined by this class loader,
|
||||
* or {@code null} if not found
|
||||
* @return The {@code Package} of the given name that has been defined
|
||||
* by this class loader, or {@code null} if not found
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if {@code name} is {@code null}.
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
|
@ -2211,14 +2215,18 @@ public abstract class ClassLoader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns all of the {@code Package}s defined by this class loader.
|
||||
* The returned array has no duplicated {@code Package}s of the same name.
|
||||
* Returns all of the {@code Package}s that have been defined by
|
||||
* this class loader. The returned array has no duplicated {@code Package}s
|
||||
* of the same name.
|
||||
*
|
||||
* @apiNote This method returns an array rather than a {@code Set} or {@code Stream}
|
||||
* for consistency with the existing {@link #getPackages} method.
|
||||
*
|
||||
* @return The array of {@code Package} objects defined by this class loader;
|
||||
* or an zero length array if no package has been defined by this class loader.
|
||||
* @return The array of {@code Package} objects that have been defined by
|
||||
* this class loader; or an zero length array if no package has been
|
||||
* defined by this class loader.
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
|
@ -2244,7 +2252,7 @@ public abstract class ClassLoader {
|
|||
* @param name
|
||||
* The <a href="#name">package name</a>
|
||||
*
|
||||
* @return The {@code Package} corresponding to the given name defined by
|
||||
* @return The {@code Package} of the given name that has been defined by
|
||||
* this class loader or its ancestors, or {@code null} if not found.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
|
@ -2263,6 +2271,8 @@ public abstract class ClassLoader {
|
|||
* {@link ClassLoader#getDefinedPackage} method which returns
|
||||
* a {@code Package} for the specified class loader.
|
||||
*
|
||||
* @see ClassLoader#getDefinedPackage(String)
|
||||
*
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
|
@ -2281,10 +2291,10 @@ public abstract class ClassLoader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns all of the {@code Package}s defined by this class loader
|
||||
* and its ancestors. The returned array may contain more than one
|
||||
* {@code Package} object of the same package name, each defined by
|
||||
* a different class loader in the class loader hierarchy.
|
||||
* Returns all of the {@code Package}s that have been defined by
|
||||
* this class loader and its ancestors. The returned array may contain
|
||||
* more than one {@code Package} object of the same package name, each
|
||||
* defined by a different class loader in the class loader hierarchy.
|
||||
*
|
||||
* @apiNote The {@link #getPlatformClassLoader() platform class loader}
|
||||
* may delegate to the application class loader. In other words,
|
||||
|
@ -2294,8 +2304,10 @@ public abstract class ClassLoader {
|
|||
* when invoked on the platform class loader, this method will not
|
||||
* return any packages defined to the application class loader.
|
||||
*
|
||||
* @return The array of {@code Package} objects defined by this
|
||||
* class loader and its ancestors
|
||||
* @return The array of {@code Package} objects that have been defined by
|
||||
* this class loader and its ancestors
|
||||
*
|
||||
* @see ClassLoader#getDefinedPackages()
|
||||
*
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
|
|
|
@ -29,6 +29,7 @@ import jdk.internal.misc.SharedSecrets;
|
|||
|
||||
import static java.lang.StackWalker.Option.*;
|
||||
import java.lang.StackWalker.StackFrame;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
class StackFrameInfo implements StackFrame {
|
||||
private final static JavaLangInvokeAccess JLIA =
|
||||
|
@ -78,6 +79,17 @@ class StackFrameInfo implements StackFrame {
|
|||
return JLIA.getName(memberName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodType getMethodType() {
|
||||
walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
|
||||
return JLIA.getMethodType(memberName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescriptor() {
|
||||
return JLIA.getMethodDescriptor(memberName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getByteCodeIndex() {
|
||||
// bci not available for native methods
|
||||
|
|
|
@ -26,10 +26,12 @@ package java.lang;
|
|||
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -96,7 +98,7 @@ public final class StackWalker {
|
|||
* @since 9
|
||||
* @jvms 2.6
|
||||
*/
|
||||
public static interface StackFrame {
|
||||
public interface StackFrame {
|
||||
/**
|
||||
* Gets the <a href="ClassLoader.html#name">binary name</a>
|
||||
* of the declaring class of the method represented by this stack frame.
|
||||
|
@ -127,6 +129,47 @@ public final class StackWalker {
|
|||
*/
|
||||
public Class<?> getDeclaringClass();
|
||||
|
||||
/**
|
||||
* Returns the {@link MethodType} representing the parameter types and
|
||||
* the return type for the method represented by this stack frame.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation throws {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @return the {@code MethodType} for this stack frame
|
||||
*
|
||||
* @throws UnsupportedOperationException if this {@code StackWalker}
|
||||
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
|
||||
* Option.RETAIN_CLASS_REFERENCE}.
|
||||
*
|
||||
* @since 10
|
||||
*/
|
||||
public default MethodType getMethodType() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <i>descriptor</i> of the method represented by
|
||||
* this stack frame as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation throws {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @return the descriptor of the method represented by
|
||||
* this stack frame
|
||||
*
|
||||
* @see MethodType#fromMethodDescriptorString(String, ClassLoader)
|
||||
* @see MethodType#toMethodDescriptorString()
|
||||
* @jvms 4.3.3 Method Descriptor
|
||||
*
|
||||
* @since 10
|
||||
*/
|
||||
public default String getDescriptor() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index to the code array of the {@code Code} attribute
|
||||
* containing the execution point represented by this stack frame.
|
||||
|
|
|
@ -28,6 +28,7 @@ package java.lang.invoke;
|
|||
import java.util.Arrays;
|
||||
import static java.lang.invoke.LambdaForm.*;
|
||||
import static java.lang.invoke.LambdaForm.Kind.*;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeVirtual;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
|
||||
/**
|
||||
|
@ -158,8 +159,11 @@ abstract class DelegatingMethodHandle extends MethodHandle {
|
|||
static final NamedFunction NF_getTarget;
|
||||
static {
|
||||
try {
|
||||
NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
|
||||
.getDeclaredMethod("getTarget"));
|
||||
MemberName member = new MemberName(DelegatingMethodHandle.class, "getTarget",
|
||||
MethodType.methodType(MethodHandle.class), REF_invokeVirtual);
|
||||
NF_getTarget = new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, NoSuchMethodException.class));
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
|
|
|
@ -753,42 +753,38 @@ class DirectMethodHandle extends MethodHandle {
|
|||
return nf;
|
||||
}
|
||||
|
||||
private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
|
||||
|
||||
private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
|
||||
|
||||
private static NamedFunction createFunction(byte func) {
|
||||
try {
|
||||
switch (func) {
|
||||
case NF_internalMemberName:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("internalMemberName", Object.class));
|
||||
return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
|
||||
case NF_internalMemberNameEnsureInit:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("internalMemberNameEnsureInit", Object.class));
|
||||
return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
|
||||
case NF_ensureInitialized:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("ensureInitialized", Object.class));
|
||||
return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
|
||||
case NF_fieldOffset:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("fieldOffset", Object.class));
|
||||
return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
|
||||
case NF_checkBase:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("checkBase", Object.class));
|
||||
return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
|
||||
case NF_staticBase:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("staticBase", Object.class));
|
||||
return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
|
||||
case NF_staticOffset:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("staticOffset", Object.class));
|
||||
return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
|
||||
case NF_checkCast:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("checkCast", Object.class, Object.class));
|
||||
return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
|
||||
case NF_allocateInstance:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("allocateInstance", Object.class));
|
||||
return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
|
||||
case NF_constructorMethod:
|
||||
return new NamedFunction(DirectMethodHandle.class
|
||||
.getDeclaredMethod("constructorMethod", Object.class));
|
||||
return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
|
||||
case NF_UNSAFE:
|
||||
return new NamedFunction(new MemberName(MethodHandleStatics.class
|
||||
.getDeclaredField("UNSAFE")));
|
||||
MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||
default:
|
||||
throw newInternalError("Unknown function: " + func);
|
||||
}
|
||||
|
@ -797,6 +793,15 @@ class DirectMethodHandle extends MethodHandle {
|
|||
}
|
||||
}
|
||||
|
||||
private static NamedFunction getNamedFunction(String name, MethodType type)
|
||||
throws ReflectiveOperationException
|
||||
{
|
||||
MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||
}
|
||||
|
||||
static {
|
||||
// The Holder class will contain pre-generated DirectMethodHandles resolved
|
||||
// speculatively using MemberName.getFactory().resolveOrNull. However, that
|
||||
|
|
|
@ -611,23 +611,17 @@ class Invokers {
|
|||
try {
|
||||
switch (func) {
|
||||
case NF_checkExactType:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("checkExactType", MethodHandle.class, MethodType.class));
|
||||
return getNamedFunction("checkExactType", MethodType.methodType(void.class, MethodHandle.class, MethodType.class));
|
||||
case NF_checkGenericType:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("checkGenericType", MethodHandle.class, MethodType.class));
|
||||
return getNamedFunction("checkGenericType", MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
|
||||
case NF_getCallSiteTarget:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("getCallSiteTarget", CallSite.class));
|
||||
return getNamedFunction("getCallSiteTarget", MethodType.methodType(MethodHandle.class, CallSite.class));
|
||||
case NF_checkCustomized:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("checkCustomized", MethodHandle.class));
|
||||
return getNamedFunction("checkCustomized", MethodType.methodType(void.class, MethodHandle.class));
|
||||
case NF_checkVarHandleGenericType:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||
return getNamedFunction("checkVarHandleGenericType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||
case NF_checkVarHandleExactType:
|
||||
return new NamedFunction(Invokers.class
|
||||
.getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||
return getNamedFunction("checkVarHandleExactType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||
default:
|
||||
throw newInternalError("Unknown function: " + func);
|
||||
}
|
||||
|
@ -636,6 +630,15 @@ class Invokers {
|
|||
}
|
||||
}
|
||||
|
||||
private static NamedFunction getNamedFunction(String name, MethodType type)
|
||||
throws ReflectiveOperationException
|
||||
{
|
||||
MemberName member = new MemberName(Invokers.class, name, type, REF_invokeStatic);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeStatic, member, Invokers.class, NoSuchMethodException.class));
|
||||
}
|
||||
|
||||
private static class Lazy {
|
||||
private static final MethodHandle MH_asSpreader;
|
||||
|
||||
|
|
|
@ -162,6 +162,29 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
|||
return (MethodType) type;
|
||||
}
|
||||
|
||||
/** Return the descriptor of this member, which
|
||||
* must be a method or constructor.
|
||||
*/
|
||||
String getMethodDescriptor() {
|
||||
if (type == null) {
|
||||
expandFromVM();
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!isInvocable()) {
|
||||
throw newIllegalArgumentException("not invocable, no method type");
|
||||
}
|
||||
|
||||
// Get a snapshot of type which doesn't get changed by racing threads.
|
||||
final Object type = this.type;
|
||||
if (type instanceof String) {
|
||||
return (String) type;
|
||||
} else {
|
||||
return getMethodType().toMethodDescriptorString();
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the actual type under which this method or constructor must be invoked.
|
||||
* For non-static methods or constructors, this is the type with a leading parameter,
|
||||
* a reference to declaring class. For static methods, it is the same as the declared type.
|
||||
|
|
|
@ -1785,6 +1785,18 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||
return memberName.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodType getMethodType(Object mname) {
|
||||
MemberName memberName = (MemberName)mname;
|
||||
return memberName.getMethodType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodDescriptor(Object mname) {
|
||||
MemberName memberName = (MemberName)mname;
|
||||
return memberName.getMethodDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNative(Object mname) {
|
||||
MemberName memberName = (MemberName)mname;
|
||||
|
|
|
@ -211,7 +211,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
|||
}
|
||||
|
||||
/**
|
||||
* Increments i, mod modulus.
|
||||
* Circularly increments i, mod modulus.
|
||||
* Precondition and postcondition: 0 <= i < modulus.
|
||||
*/
|
||||
static final int inc(int i, int modulus) {
|
||||
|
@ -220,7 +220,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
|||
}
|
||||
|
||||
/**
|
||||
* Decrements i, mod modulus.
|
||||
* Circularly decrements i, mod modulus.
|
||||
* Precondition and postcondition: 0 <= i < modulus.
|
||||
*/
|
||||
static final int dec(int i, int modulus) {
|
||||
|
@ -233,7 +233,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
|||
* Precondition: 0 <= i < modulus, 0 <= distance <= modulus.
|
||||
* @return index 0 <= i < modulus
|
||||
*/
|
||||
static final int add(int i, int distance, int modulus) {
|
||||
static final int inc(int i, int distance, int modulus) {
|
||||
if ((i += distance) - modulus >= 0) i -= modulus;
|
||||
return i;
|
||||
}
|
||||
|
@ -825,7 +825,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
|||
final int i, n;
|
||||
return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
|
||||
? null
|
||||
: new DeqSpliterator(i, cursor = add(i, n, es.length));
|
||||
: new DeqSpliterator(i, cursor = inc(i, n, es.length));
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
|
|
|
@ -490,7 +490,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Map.putAll and Map constructor
|
||||
* Implements Map.putAll and Map constructor.
|
||||
*
|
||||
* @param m the map
|
||||
* @param evict false when initially constructing this map, else
|
||||
|
@ -557,7 +557,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Map.get and related methods
|
||||
* Implements Map.get and related methods.
|
||||
*
|
||||
* @param hash hash for key
|
||||
* @param key the key
|
||||
|
@ -612,7 +612,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Map.put and related methods
|
||||
* Implements Map.put and related methods.
|
||||
*
|
||||
* @param hash hash for key
|
||||
* @param key the key
|
||||
|
@ -700,7 +700,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
threshold = newThr;
|
||||
@SuppressWarnings({"rawtypes","unchecked"})
|
||||
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
|
||||
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
|
||||
table = newTab;
|
||||
if (oldTab != null) {
|
||||
for (int j = 0; j < oldCap; ++j) {
|
||||
|
@ -800,7 +800,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Map.remove and related methods
|
||||
* Implements Map.remove and related methods.
|
||||
*
|
||||
* @param hash hash for key
|
||||
* @param key the key
|
||||
|
@ -875,7 +875,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
public boolean containsValue(Object value) {
|
||||
Node<K,V>[] tab; V v;
|
||||
if ((tab = table) != null && size > 0) {
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next) {
|
||||
if ((v = e.value) == value ||
|
||||
(value != null && value.equals(v)))
|
||||
|
@ -927,7 +927,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
throw new NullPointerException();
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
int mc = modCount;
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next)
|
||||
action.accept(e.key);
|
||||
}
|
||||
|
@ -975,7 +975,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
throw new NullPointerException();
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
int mc = modCount;
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next)
|
||||
action.accept(e.value);
|
||||
}
|
||||
|
@ -1038,7 +1038,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
throw new NullPointerException();
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
int mc = modCount;
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next)
|
||||
action.accept(e);
|
||||
}
|
||||
|
@ -1335,7 +1335,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
throw new NullPointerException();
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
int mc = modCount;
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next)
|
||||
action.accept(e.key, e.value);
|
||||
}
|
||||
|
@ -1351,7 +1351,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
throw new NullPointerException();
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
int mc = modCount;
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next) {
|
||||
e.value = function.apply(e.key, e.value);
|
||||
}
|
||||
|
@ -1394,9 +1394,10 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Save the state of the {@code HashMap} instance to a stream (i.e.,
|
||||
* serialize it).
|
||||
* Saves this map to a stream (that is, serializes it).
|
||||
*
|
||||
* @param s the stream
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @serialData The <i>capacity</i> of the HashMap (the length of the
|
||||
* bucket array) is emitted (int), followed by the
|
||||
* <i>size</i> (an int, the number of key-value
|
||||
|
@ -1415,8 +1416,11 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Reconstitute the {@code HashMap} instance from a stream (i.e.,
|
||||
* deserialize it).
|
||||
* Reconstitutes this map from a stream (that is, deserializes it).
|
||||
* @param s the stream
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
private void readObject(java.io.ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
@ -1445,7 +1449,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
|
||||
(int)ft : Integer.MAX_VALUE);
|
||||
@SuppressWarnings({"rawtypes","unchecked"})
|
||||
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
|
||||
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
|
||||
table = tab;
|
||||
|
||||
// Read the keys and values, and put the mappings in the HashMap
|
||||
|
@ -1830,7 +1834,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
|
||||
Node<K,V>[] tab;
|
||||
if (size > 0 && (tab = table) != null) {
|
||||
for (Node<K, V> e : tab) {
|
||||
for (Node<K,V> e : tab) {
|
||||
for (; e != null; e = e.next) {
|
||||
s.writeObject(e.key);
|
||||
s.writeObject(e.value);
|
||||
|
@ -1951,7 +1955,6 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
|
||||
/**
|
||||
* Forms tree of the nodes linked from this node.
|
||||
* @return root of tree
|
||||
*/
|
||||
final void treeify(Node<K,V>[] tab) {
|
||||
TreeNode<K,V> root = null;
|
||||
|
@ -2089,8 +2092,11 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
return;
|
||||
if (root.parent != null)
|
||||
root = root.root();
|
||||
if (root == null || root.right == null ||
|
||||
(rl = root.left) == null || rl.left == null) {
|
||||
if (root == null
|
||||
|| (movable
|
||||
&& (root.right == null
|
||||
|| (rl = root.left) == null
|
||||
|| rl.left == null))) {
|
||||
tab[index] = first.untreeify(map); // too small
|
||||
return;
|
||||
}
|
||||
|
@ -2319,7 +2325,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
|
||||
static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
|
||||
TreeNode<K,V> x) {
|
||||
for (TreeNode<K,V> xp, xpl, xpr;;) {
|
||||
for (TreeNode<K,V> xp, xpl, xpr;;) {
|
||||
if (x == null || x == root)
|
||||
return root;
|
||||
else if ((xp = x.parent) == null) {
|
||||
|
|
|
@ -2490,13 +2490,13 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
|||
for (Completion p = stack; p != null; p = p.next)
|
||||
++count;
|
||||
return super.toString() +
|
||||
((r == null) ?
|
||||
((count == 0) ?
|
||||
"[Not completed]" :
|
||||
"[Not completed, " + count + " dependents]") :
|
||||
(((r instanceof AltResult) && ((AltResult)r).ex != null) ?
|
||||
"[Completed exceptionally]" :
|
||||
"[Completed normally]"));
|
||||
((r == null)
|
||||
? ((count == 0)
|
||||
? "[Not completed]"
|
||||
: "[Not completed, " + count + " dependents]")
|
||||
: (((r instanceof AltResult) && ((AltResult)r).ex != null)
|
||||
? "[Completed exceptionally: " + ((AltResult)r).ex + "]"
|
||||
: "[Completed normally]"));
|
||||
}
|
||||
|
||||
// jdk9 additions
|
||||
|
|
|
@ -1394,8 +1394,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Saves the state of the {@code ConcurrentHashMap} instance to a
|
||||
* stream (i.e., serializes it).
|
||||
* Saves this map to a stream (that is, serializes it).
|
||||
*
|
||||
* @param s the stream
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
* @serialData
|
||||
|
@ -1439,7 +1439,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
|||
}
|
||||
|
||||
/**
|
||||
* Reconstitutes the instance from a stream (that is, deserializes it).
|
||||
* Reconstitutes this map from a stream (that is, deserializes it).
|
||||
* @param s the stream
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -174,6 +174,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
|
|||
this.completionQueue = completionQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RejectedExecutionException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public Future<V> submit(Callable<V> task) {
|
||||
if (task == null) throw new NullPointerException();
|
||||
RunnableFuture<V> f = newTaskFor(task);
|
||||
|
@ -181,6 +185,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
|
|||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RejectedExecutionException {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public Future<V> submit(Runnable task, V result) {
|
||||
if (task == null) throw new NullPointerException();
|
||||
RunnableFuture<V> f = newTaskFor(task, result);
|
||||
|
|
|
@ -514,6 +514,9 @@ public class Executors {
|
|||
task.run();
|
||||
return result;
|
||||
}
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + task + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -540,6 +543,10 @@ public class Executors {
|
|||
throw e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + task + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -592,6 +599,10 @@ public class Executors {
|
|||
throw e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + task + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1375,6 +1375,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
|||
public final void setRawResult(T v) { result = v; }
|
||||
public final boolean exec() { runnable.run(); return true; }
|
||||
public final void run() { invoke(); }
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + runnable + "]";
|
||||
}
|
||||
private static final long serialVersionUID = 5232453952276885070L;
|
||||
}
|
||||
|
||||
|
@ -1392,6 +1395,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
|||
public final void setRawResult(Void v) { }
|
||||
public final boolean exec() { runnable.run(); return true; }
|
||||
public final void run() { invoke(); }
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + runnable + "]";
|
||||
}
|
||||
private static final long serialVersionUID = 5232453952276885070L;
|
||||
}
|
||||
|
||||
|
@ -1437,6 +1443,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
|||
}
|
||||
}
|
||||
public final void run() { invoke(); }
|
||||
public String toString() {
|
||||
return super.toString() + "[Wrapped task = " + callable + "]";
|
||||
}
|
||||
private static final long serialVersionUID = 2838392045355241008L;
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,41 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this FutureTask.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation returns a string identifying this
|
||||
* FutureTask, as well as its completion state. The state, in
|
||||
* brackets, contains one of the strings {@code "Completed Normally"},
|
||||
* {@code "Completed Exceptionally"}, {@code "Cancelled"}, or {@code
|
||||
* "Not completed"}.
|
||||
*
|
||||
* @return a string representation of this FutureTask
|
||||
*/
|
||||
public String toString() {
|
||||
final String status;
|
||||
switch (state) {
|
||||
case NORMAL:
|
||||
status = "[Completed normally]";
|
||||
break;
|
||||
case EXCEPTIONAL:
|
||||
status = "[Completed exceptionally: " + outcome + "]";
|
||||
break;
|
||||
case CANCELLED:
|
||||
case INTERRUPTING:
|
||||
case INTERRUPTED:
|
||||
status = "[Cancelled]";
|
||||
break;
|
||||
default:
|
||||
final Callable<?> callable = this.callable;
|
||||
status = (callable == null)
|
||||
? "[Not completed]"
|
||||
: "[Not completed, task = " + callable + "]";
|
||||
}
|
||||
return super.toString() + status;
|
||||
}
|
||||
|
||||
// VarHandle mechanics
|
||||
private static final VarHandle STATE;
|
||||
private static final VarHandle RUNNER;
|
||||
|
|
|
@ -383,7 +383,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
*/
|
||||
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
|
||||
private static final int COUNT_BITS = Integer.SIZE - 3;
|
||||
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
|
||||
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
|
||||
|
||||
// runState is stored in the high-order bits
|
||||
private static final int RUNNING = -1 << COUNT_BITS;
|
||||
|
@ -393,8 +393,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
private static final int TERMINATED = 3 << COUNT_BITS;
|
||||
|
||||
// Packing and unpacking ctl
|
||||
private static int runStateOf(int c) { return c & ~CAPACITY; }
|
||||
private static int workerCountOf(int c) { return c & CAPACITY; }
|
||||
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
|
||||
private static int workerCountOf(int c) { return c & COUNT_MASK; }
|
||||
private static int ctlOf(int rs, int wc) { return rs | wc; }
|
||||
|
||||
/*
|
||||
|
@ -434,7 +434,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
* decrements are performed within getTask.
|
||||
*/
|
||||
private void decrementWorkerCount() {
|
||||
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
|
||||
ctl.addAndGet(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -538,12 +538,17 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
* Core pool size is the minimum number of workers to keep alive
|
||||
* (and not allow to time out etc) unless allowCoreThreadTimeOut
|
||||
* is set, in which case the minimum is zero.
|
||||
*
|
||||
* Since the worker count is actually stored in COUNT_BITS bits,
|
||||
* the effective limit is {@code corePoolSize & COUNT_MASK}.
|
||||
*/
|
||||
private volatile int corePoolSize;
|
||||
|
||||
/**
|
||||
* Maximum pool size. Note that the actual maximum is internally
|
||||
* bounded by CAPACITY.
|
||||
* Maximum pool size.
|
||||
*
|
||||
* Since the worker count is actually stored in COUNT_BITS bits,
|
||||
* the effective limit is {@code maximumPoolSize & COUNT_MASK}.
|
||||
*/
|
||||
private volatile int maximumPoolSize;
|
||||
|
||||
|
@ -705,7 +710,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
int c = ctl.get();
|
||||
if (isRunning(c) ||
|
||||
runStateAtLeast(c, TIDYING) ||
|
||||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
|
||||
(runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
|
||||
return;
|
||||
if (workerCountOf(c) != 0) { // Eligible to terminate
|
||||
interruptIdleWorkers(ONLY_ONE);
|
||||
|
@ -744,17 +749,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
* specially.
|
||||
*/
|
||||
private void checkShutdownAccess() {
|
||||
// assert mainLock.isHeldByCurrentThread();
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkPermission(shutdownPerm);
|
||||
final ReentrantLock mainLock = this.mainLock;
|
||||
mainLock.lock();
|
||||
try {
|
||||
for (Worker w : workers)
|
||||
security.checkAccess(w.thread);
|
||||
} finally {
|
||||
mainLock.unlock();
|
||||
}
|
||||
for (Worker w : workers)
|
||||
security.checkAccess(w.thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,14 +763,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
* (in which case some threads may remain uninterrupted).
|
||||
*/
|
||||
private void interruptWorkers() {
|
||||
final ReentrantLock mainLock = this.mainLock;
|
||||
mainLock.lock();
|
||||
try {
|
||||
for (Worker w : workers)
|
||||
w.interruptIfStarted();
|
||||
} finally {
|
||||
mainLock.unlock();
|
||||
}
|
||||
// assert mainLock.isHeldByCurrentThread();
|
||||
for (Worker w : workers)
|
||||
w.interruptIfStarted();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -896,26 +891,22 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
*/
|
||||
private boolean addWorker(Runnable firstTask, boolean core) {
|
||||
retry:
|
||||
for (;;) {
|
||||
int c = ctl.get();
|
||||
int rs = runStateOf(c);
|
||||
|
||||
for (int c = ctl.get();;) {
|
||||
// Check if queue empty only if necessary.
|
||||
if (rs >= SHUTDOWN &&
|
||||
! (rs == SHUTDOWN &&
|
||||
firstTask == null &&
|
||||
! workQueue.isEmpty()))
|
||||
if (runStateAtLeast(c, SHUTDOWN)
|
||||
&& (runStateAtLeast(c, STOP)
|
||||
|| firstTask != null
|
||||
|| workQueue.isEmpty()))
|
||||
return false;
|
||||
|
||||
for (;;) {
|
||||
int wc = workerCountOf(c);
|
||||
if (wc >= CAPACITY ||
|
||||
wc >= (core ? corePoolSize : maximumPoolSize))
|
||||
if (workerCountOf(c)
|
||||
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
|
||||
return false;
|
||||
if (compareAndIncrementWorkerCount(c))
|
||||
break retry;
|
||||
c = ctl.get(); // Re-read ctl
|
||||
if (runStateOf(c) != rs)
|
||||
if (runStateAtLeast(c, SHUTDOWN))
|
||||
continue retry;
|
||||
// else CAS failed due to workerCount change; retry inner loop
|
||||
}
|
||||
|
@ -934,10 +925,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
// Recheck while holding lock.
|
||||
// Back out on ThreadFactory failure or if
|
||||
// shut down before lock acquired.
|
||||
int rs = runStateOf(ctl.get());
|
||||
int c = ctl.get();
|
||||
|
||||
if (rs < SHUTDOWN ||
|
||||
(rs == SHUTDOWN && firstTask == null)) {
|
||||
if (isRunning(c) ||
|
||||
(runStateLessThan(c, STOP) && firstTask == null)) {
|
||||
if (t.isAlive()) // precheck that t is startable
|
||||
throw new IllegalThreadStateException();
|
||||
workers.add(w);
|
||||
|
@ -1044,10 +1035,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
|
||||
for (;;) {
|
||||
int c = ctl.get();
|
||||
int rs = runStateOf(c);
|
||||
|
||||
// Check if queue empty only if necessary.
|
||||
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
|
||||
if (runStateAtLeast(c, SHUTDOWN)
|
||||
&& (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
|
||||
decrementWorkerCount();
|
||||
return null;
|
||||
}
|
||||
|
@ -1140,17 +1131,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
wt.interrupt();
|
||||
try {
|
||||
beforeExecute(wt, task);
|
||||
Throwable thrown = null;
|
||||
try {
|
||||
task.run();
|
||||
} catch (RuntimeException x) {
|
||||
thrown = x; throw x;
|
||||
} catch (Error x) {
|
||||
thrown = x; throw x;
|
||||
} catch (Throwable x) {
|
||||
thrown = x; throw new Error(x);
|
||||
} finally {
|
||||
afterExecute(task, thrown);
|
||||
afterExecute(task, null);
|
||||
} catch (Throwable ex) {
|
||||
afterExecute(task, ex);
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
task = null;
|
||||
|
@ -1331,7 +1317,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
*
|
||||
* If the task cannot be submitted for execution, either because this
|
||||
* executor has been shutdown or because its capacity has been reached,
|
||||
* the task is handled by the current {@code RejectedExecutionHandler}.
|
||||
* the task is handled by the current {@link RejectedExecutionHandler}.
|
||||
*
|
||||
* @param command the task to execute
|
||||
* @throws RejectedExecutionException at discretion of
|
||||
|
@ -1438,7 +1424,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
}
|
||||
|
||||
public boolean isShutdown() {
|
||||
return ! isRunning(ctl.get());
|
||||
return runStateAtLeast(ctl.get(), SHUTDOWN);
|
||||
}
|
||||
|
||||
/** Used by ScheduledThreadPoolExecutor. */
|
||||
|
@ -1459,7 +1445,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
*/
|
||||
public boolean isTerminating() {
|
||||
int c = ctl.get();
|
||||
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
|
||||
return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
|
||||
}
|
||||
|
||||
public boolean isTerminated() {
|
||||
|
@ -1472,7 +1458,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
final ReentrantLock mainLock = this.mainLock;
|
||||
mainLock.lock();
|
||||
try {
|
||||
while (!runStateAtLeast(ctl.get(), TERMINATED)) {
|
||||
while (runStateLessThan(ctl.get(), TERMINATED)) {
|
||||
if (nanos <= 0L)
|
||||
return false;
|
||||
nanos = termination.awaitNanos(nanos);
|
||||
|
@ -1951,7 +1937,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
|||
}
|
||||
int c = ctl.get();
|
||||
String runState =
|
||||
runStateLessThan(c, SHUTDOWN) ? "Running" :
|
||||
isRunning(c) ? "Running" :
|
||||
runStateAtLeast(c, TERMINATED) ? "Terminated" :
|
||||
"Shutting down";
|
||||
return super.toString() +
|
||||
|
|
|
@ -342,11 +342,13 @@ public enum TimeUnit {
|
|||
* using:
|
||||
*
|
||||
* <pre> {@code
|
||||
* public synchronized Object poll(long timeout, TimeUnit unit)
|
||||
* public E poll(long timeout, TimeUnit unit)
|
||||
* throws InterruptedException {
|
||||
* while (empty) {
|
||||
* unit.timedWait(this, timeout);
|
||||
* ...
|
||||
* synchronized (lock) {
|
||||
* while (isEmpty()) {
|
||||
* unit.timedWait(lock, timeout);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
|
|
|
@ -67,11 +67,11 @@ public abstract class AbstractQueuedLongSynchronizer
|
|||
private static final long serialVersionUID = 7373984972572414692L;
|
||||
|
||||
/*
|
||||
To keep sources in sync, the remainder of this source file is
|
||||
exactly cloned from AbstractQueuedSynchronizer, replacing class
|
||||
name and changing ints related with sync state to longs. Please
|
||||
keep it that way.
|
||||
*/
|
||||
* To keep sources in sync, the remainder of this source file is
|
||||
* exactly cloned from AbstractQueuedSynchronizer, replacing class
|
||||
* name and changing ints related with sync state to longs. Please
|
||||
* keep it that way.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new {@code AbstractQueuedLongSynchronizer} instance
|
||||
|
@ -725,8 +725,7 @@ public abstract class AbstractQueuedLongSynchronizer
|
|||
/**
|
||||
* Returns {@code true} if synchronization is held exclusively with
|
||||
* respect to the current (calling) thread. This method is invoked
|
||||
* upon each call to a non-waiting {@link ConditionObject} method.
|
||||
* (Waiting methods instead invoke {@link #release}.)
|
||||
* upon each call to a {@link ConditionObject} method.
|
||||
*
|
||||
* <p>The default implementation throws {@link
|
||||
* UnsupportedOperationException}. This method is invoked
|
||||
|
@ -1366,9 +1365,8 @@ public abstract class AbstractQueuedLongSynchronizer
|
|||
}
|
||||
|
||||
/**
|
||||
* Condition implementation for a {@link
|
||||
* AbstractQueuedLongSynchronizer} serving as the basis of a {@link
|
||||
* Lock} implementation.
|
||||
* Condition implementation for a {@link AbstractQueuedLongSynchronizer}
|
||||
* serving as the basis of a {@link Lock} implementation.
|
||||
*
|
||||
* <p>Method documentation for this class describes mechanics,
|
||||
* not behavioral specifications from the point of view of Lock
|
||||
|
@ -1401,6 +1399,8 @@ public abstract class AbstractQueuedLongSynchronizer
|
|||
* @return its new wait node
|
||||
*/
|
||||
private Node addConditionWaiter() {
|
||||
if (!isHeldExclusively())
|
||||
throw new IllegalMonitorStateException();
|
||||
Node t = lastWaiter;
|
||||
// If lastWaiter is cancelled, clean out.
|
||||
if (t != null && t.waitStatus != Node.CONDITION) {
|
||||
|
|
|
@ -194,19 +194,13 @@ import java.util.concurrent.TimeUnit;
|
|||
* represent the locked state. While a non-reentrant lock
|
||||
* does not strictly require recording of the current owner
|
||||
* thread, this class does so anyway to make usage easier to monitor.
|
||||
* It also supports conditions and exposes
|
||||
* one of the instrumentation methods:
|
||||
* It also supports conditions and exposes some instrumentation methods:
|
||||
*
|
||||
* <pre> {@code
|
||||
* class Mutex implements Lock, java.io.Serializable {
|
||||
*
|
||||
* // Our internal helper class
|
||||
* private static class Sync extends AbstractQueuedSynchronizer {
|
||||
* // Reports whether in locked state
|
||||
* protected boolean isHeldExclusively() {
|
||||
* return getState() == 1;
|
||||
* }
|
||||
*
|
||||
* // Acquires the lock if state is zero
|
||||
* public boolean tryAcquire(int acquires) {
|
||||
* assert acquires == 1; // Otherwise unused
|
||||
|
@ -220,14 +214,27 @@ import java.util.concurrent.TimeUnit;
|
|||
* // Releases the lock by setting state to zero
|
||||
* protected boolean tryRelease(int releases) {
|
||||
* assert releases == 1; // Otherwise unused
|
||||
* if (getState() == 0) throw new IllegalMonitorStateException();
|
||||
* if (!isHeldExclusively())
|
||||
* throw new IllegalMonitorStateException();
|
||||
* setExclusiveOwnerThread(null);
|
||||
* setState(0);
|
||||
* return true;
|
||||
* }
|
||||
*
|
||||
* // Reports whether in locked state
|
||||
* public boolean isLocked() {
|
||||
* return getState() != 0;
|
||||
* }
|
||||
*
|
||||
* public boolean isHeldExclusively() {
|
||||
* // a data race, but safe due to out-of-thin-air guarantees
|
||||
* return getExclusiveOwnerThread() == Thread.currentThread();
|
||||
* }
|
||||
*
|
||||
* // Provides a Condition
|
||||
* Condition newCondition() { return new ConditionObject(); }
|
||||
* public Condition newCondition() {
|
||||
* return new ConditionObject();
|
||||
* }
|
||||
*
|
||||
* // Deserializes properly
|
||||
* private void readObject(ObjectInputStream s)
|
||||
|
@ -240,12 +247,17 @@ import java.util.concurrent.TimeUnit;
|
|||
* // The sync object does all the hard work. We just forward to it.
|
||||
* private final Sync sync = new Sync();
|
||||
*
|
||||
* public void lock() { sync.acquire(1); }
|
||||
* public boolean tryLock() { return sync.tryAcquire(1); }
|
||||
* public void unlock() { sync.release(1); }
|
||||
* public Condition newCondition() { return sync.newCondition(); }
|
||||
* public boolean isLocked() { return sync.isHeldExclusively(); }
|
||||
* public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
|
||||
* public void lock() { sync.acquire(1); }
|
||||
* public boolean tryLock() { return sync.tryAcquire(1); }
|
||||
* public void unlock() { sync.release(1); }
|
||||
* public Condition newCondition() { return sync.newCondition(); }
|
||||
* public boolean isLocked() { return sync.isLocked(); }
|
||||
* public boolean isHeldByCurrentThread() {
|
||||
* return sync.isHeldExclusively();
|
||||
* }
|
||||
* public boolean hasQueuedThreads() {
|
||||
* return sync.hasQueuedThreads();
|
||||
* }
|
||||
* public void lockInterruptibly() throws InterruptedException {
|
||||
* sync.acquireInterruptibly(1);
|
||||
* }
|
||||
|
@ -1193,8 +1205,7 @@ public abstract class AbstractQueuedSynchronizer
|
|||
/**
|
||||
* Returns {@code true} if synchronization is held exclusively with
|
||||
* respect to the current (calling) thread. This method is invoked
|
||||
* upon each call to a non-waiting {@link ConditionObject} method.
|
||||
* (Waiting methods instead invoke {@link #release}.)
|
||||
* upon each call to a {@link ConditionObject} method.
|
||||
*
|
||||
* <p>The default implementation throws {@link
|
||||
* UnsupportedOperationException}. This method is invoked
|
||||
|
@ -1834,9 +1845,8 @@ public abstract class AbstractQueuedSynchronizer
|
|||
}
|
||||
|
||||
/**
|
||||
* Condition implementation for a {@link
|
||||
* AbstractQueuedSynchronizer} serving as the basis of a {@link
|
||||
* Lock} implementation.
|
||||
* Condition implementation for a {@link AbstractQueuedSynchronizer}
|
||||
* serving as the basis of a {@link Lock} implementation.
|
||||
*
|
||||
* <p>Method documentation for this class describes mechanics,
|
||||
* not behavioral specifications from the point of view of Lock
|
||||
|
@ -1867,6 +1877,8 @@ public abstract class AbstractQueuedSynchronizer
|
|||
* @return its new wait node
|
||||
*/
|
||||
private Node addConditionWaiter() {
|
||||
if (!isHeldExclusively())
|
||||
throw new IllegalMonitorStateException();
|
||||
Node t = lastWaiter;
|
||||
// If lastWaiter is cancelled, clean out.
|
||||
if (t != null && t.waitStatus != Node.CONDITION) {
|
||||
|
|
|
@ -73,7 +73,7 @@ import java.util.concurrent.TimeUnit;
|
|||
* available in the buffer. This can be achieved using two
|
||||
* {@link Condition} instances.
|
||||
* <pre>
|
||||
* class BoundedBuffer {
|
||||
* class BoundedBuffer<E> {
|
||||
* <b>final Lock lock = new ReentrantLock();</b>
|
||||
* final Condition notFull = <b>lock.newCondition(); </b>
|
||||
* final Condition notEmpty = <b>lock.newCondition(); </b>
|
||||
|
@ -81,7 +81,7 @@ import java.util.concurrent.TimeUnit;
|
|||
* final Object[] items = new Object[100];
|
||||
* int putptr, takeptr, count;
|
||||
*
|
||||
* public void put(Object x) throws InterruptedException {
|
||||
* public void put(E x) throws InterruptedException {
|
||||
* <b>lock.lock();
|
||||
* try {</b>
|
||||
* while (count == items.length)
|
||||
|
@ -95,12 +95,12 @@ import java.util.concurrent.TimeUnit;
|
|||
* }</b>
|
||||
* }
|
||||
*
|
||||
* public Object take() throws InterruptedException {
|
||||
* public E take() throws InterruptedException {
|
||||
* <b>lock.lock();
|
||||
* try {</b>
|
||||
* while (count == 0)
|
||||
* <b>notEmpty.await();</b>
|
||||
* Object x = items[takeptr];
|
||||
* E x = (E) items[takeptr];
|
||||
* if (++takeptr == items.length) takeptr = 0;
|
||||
* --count;
|
||||
* <b>notFull.signal();</b>
|
||||
|
@ -310,7 +310,8 @@ public interface Condition {
|
|||
* the following form:
|
||||
*
|
||||
* <pre> {@code
|
||||
* boolean aMethod(long timeout, TimeUnit unit) {
|
||||
* boolean aMethod(long timeout, TimeUnit unit)
|
||||
* throws InterruptedException {
|
||||
* long nanos = unit.toNanos(timeout);
|
||||
* lock.lock();
|
||||
* try {
|
||||
|
@ -320,6 +321,7 @@ public interface Condition {
|
|||
* nanos = theCondition.awaitNanos(nanos);
|
||||
* }
|
||||
* // ...
|
||||
* return true;
|
||||
* } finally {
|
||||
* lock.unlock();
|
||||
* }
|
||||
|
@ -410,7 +412,8 @@ public interface Condition {
|
|||
* <p>The return value indicates whether the deadline has elapsed,
|
||||
* which can be used as follows:
|
||||
* <pre> {@code
|
||||
* boolean aMethod(Date deadline) {
|
||||
* boolean aMethod(Date deadline)
|
||||
* throws InterruptedException {
|
||||
* boolean stillWaiting = true;
|
||||
* lock.lock();
|
||||
* try {
|
||||
|
@ -420,6 +423,7 @@ public interface Condition {
|
|||
* stillWaiting = theCondition.awaitUntil(deadline);
|
||||
* }
|
||||
* // ...
|
||||
* return true;
|
||||
* } finally {
|
||||
* lock.unlock();
|
||||
* }
|
||||
|
|
|
@ -151,18 +151,20 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
|||
* }
|
||||
*
|
||||
* double distanceFromOrigin() { // A read-only method
|
||||
* double currentX, currentY;
|
||||
* long stamp = sl.tryOptimisticRead();
|
||||
* double currentX = x, currentY = y;
|
||||
* if (!sl.validate(stamp)) {
|
||||
* stamp = sl.readLock();
|
||||
* do {
|
||||
* if (stamp == 0L)
|
||||
* stamp = sl.readLock();
|
||||
* try {
|
||||
* // possibly racy reads
|
||||
* currentX = x;
|
||||
* currentY = y;
|
||||
* } finally {
|
||||
* sl.unlockRead(stamp);
|
||||
* stamp = sl.tryConvertToOptimisticRead(stamp);
|
||||
* }
|
||||
* }
|
||||
* return Math.sqrt(currentX * currentX + currentY * currentY);
|
||||
* } while (stamp == 0);
|
||||
* return Math.hypot(currentX, currentY);
|
||||
* }
|
||||
*
|
||||
* void moveIfAtOrigin(double newX, double newY) { // upgrade
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue