< prev index next >

src/java.base/share/classes/java/lang/Thread.java

Print this page
imported patch Thread-misc

*** 37,46 **** --- 37,47 ---- import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; import jdk.internal.misc.TerminatingThreadLocal; + import jdk.internal.misc.Unsafe; import sun.nio.ch.Interruptible; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import sun.security.util.SecurityConstants; import jdk.internal.HotSpotIntrinsicCandidate;
*** 146,163 **** private static native void registerNatives(); static { registerNatives(); } ! private volatile String name; private int priority; /* Whether or not the thread is a daemon thread. */ ! private boolean daemon = false; /* Fields reserved for exclusive use by the JVM */ ! private boolean stillborn = false; private long eetop; /* What will be run. */ private Runnable target; --- 147,164 ---- private static native void registerNatives(); static { registerNatives(); } ! private String name; private int priority; /* Whether or not the thread is a daemon thread. */ ! private boolean daemon; // by default false; /* Fields reserved for exclusive use by the JVM */ ! private boolean stillborn; private long eetop; /* What will be run. */ private Runnable target;
*** 174,192 **** private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ! ThreadLocal.ThreadLocalMap threadLocals = null; /* * InheritableThreadLocal values pertaining to this thread. This map is * maintained by the InheritableThreadLocal class. */ ! ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; /* * The requested stack size for this thread, or 0 if the creator did * not specify a stack size. It is up to the VM to do whatever it * likes with this number; some VMs will ignore it. --- 175,209 ---- private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } + private static final Unsafe U = Unsafe.getUnsafe(); + private static final long DAEMON = U.objectFieldOffset( + Thread.class, "daemon"); + private static final long CONTEXTCLASSLOADER = U.objectFieldOffset( + Thread.class, "contextClassLoader"); + private static final long UNCAUGHTEXCEPTIONHANDLER = U.objectFieldOffset( + Thread.class, "uncaughtExceptionHandler"); + private static final long PRIORITY = U.objectFieldOffset( + Thread.class, "priority"); + private static final long NAME = U.objectFieldOffset( + Thread.class, "name"); + + private ClassLoader contextClassLoaderAcquire() { + return (ClassLoader) U.getReferenceAcquire(this, CONTEXTCLASSLOADER); + } + /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ! ThreadLocal.ThreadLocalMap threadLocals; /* * InheritableThreadLocal values pertaining to this thread. This map is * maintained by the InheritableThreadLocal class. */ ! ThreadLocal.ThreadLocalMap inheritableThreadLocals; /* * The requested stack size for this thread, or 0 if the creator did * not specify a stack size. It is up to the VM to do whatever it * likes with this number; some VMs will ignore it.
*** 436,449 **** g.addUnstarted(); this.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); ! if (security == null || isCCLOverridden(parent.getClass())) ! this.contextClassLoader = parent.getContextClassLoader(); ! else ! this.contextClassLoader = parent.contextClassLoader; this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext(); this.target = target; setPriority(priority); if (inheritThreadLocals && parent.inheritableThreadLocals != null) --- 453,466 ---- g.addUnstarted(); this.group = g; this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); ! this.contextClassLoader = ! (security == null || isCCLOverridden(parent.getClass())) ! ? parent.getContextClassLoader() ! : parent.contextClassLoaderAcquire(); this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext(); this.target = target; setPriority(priority); if (inheritThreadLocals && parent.inheritableThreadLocals != null)
*** 452,461 **** --- 469,480 ---- /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ this.tid = nextThreadID(); + + U.storeFence(); } /** * Throws CloneNotSupportedException as a Thread can not be meaningfully * cloned. Construct a new Thread instead.
*** 1143,1164 **** } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } ! setPriority0(priority = newPriority); } } /** * Returns this thread's priority. * * @return this thread's priority. * @see #setPriority */ public final int getPriority() { ! return priority; } /** * Changes the name of this thread to be equal to the argument {@code name}. * <p> --- 1162,1184 ---- } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } ! U.putIntRelease(this, PRIORITY, newPriority); ! setPriority0(newPriority); } } /** * Returns this thread's priority. * * @return this thread's priority. * @see #setPriority */ public final int getPriority() { ! return U.getIntAcquire(this, PRIORITY); } /** * Changes the name of this thread to be equal to the argument {@code name}. * <p>
*** 1170,1199 **** * @throws SecurityException if the current thread cannot modify this * thread. * @see #getName * @see #checkAccess() */ ! public final synchronized void setName(String name) { checkAccess(); if (name == null) { throw new NullPointerException("name cannot be null"); } this.name = name; if (threadStatus != 0) { setNativeName(name); } } /** * Returns this thread's name. * * @return this thread's name. * @see #setName(String) */ public final String getName() { ! return name; } /** * Returns the thread group to which this thread belongs. * This method returns null if this thread has died --- 1190,1222 ---- * @throws SecurityException if the current thread cannot modify this * thread. * @see #getName * @see #checkAccess() */ ! public final void setName(String name) { checkAccess(); if (name == null) { throw new NullPointerException("name cannot be null"); } + synchronized (this) { this.name = name; if (threadStatus != 0) { setNativeName(name); } } + U.storeFence(); + } /** * Returns this thread's name. * * @return this thread's name. * @see #setName(String) */ public final String getName() { ! return (String) U.getReferenceAcquire(this, NAME); } /** * Returns the thread group to which this thread belongs. * This method returns null if this thread has died
*** 1336,1346 **** * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final synchronized void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } --- 1359,1369 ---- * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ ! public final void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); }
*** 1404,1425 **** public final void setDaemon(boolean on) { checkAccess(); if (isAlive()) { throw new IllegalThreadStateException(); } ! daemon = on; } /** * Tests if this thread is a daemon thread. * * @return {@code true} if this thread is a daemon thread; * {@code false} otherwise. * @see #setDaemon(boolean) */ public final boolean isDaemon() { ! return daemon; } /** * Determines if the currently running thread has permission to * modify this thread. --- 1427,1448 ---- public final void setDaemon(boolean on) { checkAccess(); if (isAlive()) { throw new IllegalThreadStateException(); } ! U.putBooleanRelease(this, DAEMON, on); } /** * Tests if this thread is a daemon thread. * * @return {@code true} if this thread is a daemon thread; * {@code false} otherwise. * @see #setDaemon(boolean) */ public final boolean isDaemon() { ! return U.getBooleanAcquire(this, DAEMON); } /** * Determines if the currently running thread has permission to * modify this thread.
*** 1445,1461 **** * * @return a string representation of this thread. */ public String toString() { ThreadGroup group = getThreadGroup(); ! if (group != null) { ! return "Thread[" + getName() + "," + getPriority() + "," + ! group.getName() + "]"; ! } else { ! return "Thread[" + getName() + "," + getPriority() + "," + ! "" + "]"; ! } } /** * Returns the context {@code ClassLoader} for this thread. The context * {@code ClassLoader} is provided by the creator of the thread for use --- 1468,1479 ---- * * @return a string representation of this thread. */ public String toString() { ThreadGroup group = getThreadGroup(); ! return "Thread[" + getName() + "," + getPriority() + "," ! + ((group != null) ? group.getName() : null) + "]"; } /** * Returns the context {@code ClassLoader} for this thread. The context * {@code ClassLoader} is provided by the creator of the thread for use
*** 1479,1496 **** * * @since 1.2 */ @CallerSensitive public ClassLoader getContextClassLoader() { ! if (contextClassLoader == null) ! return null; ! SecurityManager sm = System.getSecurityManager(); ! if (sm != null) { ! ClassLoader.checkClassLoaderPermission(contextClassLoader, ! Reflection.getCallerClass()); ! } ! return contextClassLoader; } /** * Sets the context ClassLoader for this Thread. The context * ClassLoader can be set when a thread is created, and allows --- 1497,1511 ---- * * @since 1.2 */ @CallerSensitive public ClassLoader getContextClassLoader() { ! SecurityManager sm; ! ClassLoader cl = contextClassLoaderAcquire(); ! if (cl != null && (sm = System.getSecurityManager()) != null) ! ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass()); ! return cl; } /** * Sets the context ClassLoader for this Thread. The context * ClassLoader can be set when a thread is created, and allows
*** 1516,1526 **** public void setContextClassLoader(ClassLoader cl) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("setContextClassLoader")); } ! contextClassLoader = cl; } /** * Returns {@code true} if and only if the current thread holds the * monitor lock on the specified object. --- 1531,1541 ---- public void setContextClassLoader(ClassLoader cl) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("setContextClassLoader")); } ! U.putReferenceRelease(this, CONTEXTCLASSLOADER, cl); } /** * Returns {@code true} if and only if the current thread holds the * monitor lock on the specified object.
*** 1855,1866 **** public State getState() { // get current thread state return jdk.internal.misc.VM.toThreadState(threadStatus); } - // Added in JSR-166 - /** * Interface for handlers invoked when a {@code Thread} abruptly * terminates due to an uncaught exception. * <p>When a thread is about to terminate due to an uncaught exception * the Java Virtual Machine will query the thread for its --- 1870,1879 ----
*** 1893,1903 **** */ void uncaughtException(Thread t, Throwable e); } // null unless explicitly set ! private volatile UncaughtExceptionHandler uncaughtExceptionHandler; // null unless explicitly set private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; /** --- 1906,1916 ---- */ void uncaughtException(Thread t, Throwable e); } // null unless explicitly set ! private UncaughtExceptionHandler uncaughtExceptionHandler; // null unless explicitly set private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; /**
*** 1964,1975 **** * has terminated, in which case {@code null} is returned. * @since 1.5 * @return the uncaught exception handler for this thread */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { ! return uncaughtExceptionHandler != null ? ! uncaughtExceptionHandler : group; } /** * Set the handler invoked when this thread abruptly terminates * due to an uncaught exception. --- 1977,1989 ---- * has terminated, in which case {@code null} is returned. * @since 1.5 * @return the uncaught exception handler for this thread */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { ! UncaughtExceptionHandler ueh = (UncaughtExceptionHandler) ! U.getReferenceAcquire(this, UNCAUGHTEXCEPTIONHANDLER); ! return (ueh != null) ? ueh : group; } /** * Set the handler invoked when this thread abruptly terminates * due to an uncaught exception.
*** 1985,1995 **** * @see ThreadGroup#uncaughtException * @since 1.5 */ public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { checkAccess(); ! uncaughtExceptionHandler = eh; } /** * Dispatch an uncaught exception to the handler. This method is * intended to be called only by the JVM. --- 1999,2009 ---- * @see ThreadGroup#uncaughtException * @since 1.5 */ public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { checkAccess(); ! U.putReferenceRelease(this, UNCAUGHTEXCEPTIONHANDLER, eh); } /** * Dispatch an uncaught exception to the handler. This method is * intended to be called only by the JVM.
< prev index next >