Java Thread 源码 附录

1  /*
2   * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5   * This code is free software; you can redistribute it and/or modify it
6   * under the terms of the GNU General Public License version 2 only, as
7   * published by the Free Software Foundation.  Oracle designates this
8   * particular file as subject to the "Classpath" exception as provided
9   * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
26  package java.lang;
28  import  java.lang.ref.Reference;
29  import  java.lang.ref.ReferenceQueue;
30  import  java.lang.ref.WeakReference;
31  import  java.security.AccessController;
32  import  java.security.AccessControlContext;
33  import  java.security.PrivilegedAction;
34  import  java.util.Map;
35  import  java.util.HashMap;
36  import  java.util.concurrent.ConcurrentHashMap;
37  import  java.util.concurrent.ConcurrentMap;
38  import  java.util.concurrent.locks.LockSupport;
39  import  sun.nio.ch.Interruptible;
40  import  sun.reflect.CallerSensitive;
41  import  sun.reflect.Reflection;
42  import  sun.security.util.SecurityConstants;

140  public
141  class Thread implements Runnable {
142      /* Make sure registerNatives is the first thing <clinit> does. */
143      private static native void registerNatives();
144      static {
145          registerNatives();
146      }
148      private volatile char  name[];
149      private int            priority;
150      private Thread         threadQ;
151      private long           eetop;
153      /* Whether or not to single_step this thread. */
154      private boolean     single_step;
156      /* Whether or not the thread is a daemon thread. */
157      private boolean     daemon = false;
159      /* JVM state */
160      private boolean     stillborn = false;
162      /* What will be run. */
163      private Runnable target;
165      /* The group of this thread */
166      private ThreadGroup group;
168      /* The context ClassLoader for this thread */
169      private ClassLoader contextClassLoader;
171      /* The inherited AccessControlContext of this thread */
172      private AccessControlContext inheritedAccessControlContext;
174      /* For autonumbering anonymous threads. */
175      private static int threadInitNumber;
176      private static synchronized int nextThreadNum() {
177          return ++;
178      }
180      /* ThreadLocal values pertaining to this thread. This map is maintained
181       * by the ThreadLocal class. */
182      ThreadLocal.ThreadLocalMap threadLocals = null;
184      /*
185       * InheritableThreadLocal values pertaining to this thread. This map is
186       * maintained by the InheritableThreadLocal class.
187       */
188      ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
190      /*
191       * The requested stack size for this thread, or 0 if the creator did
192       * not specify a stack size.  It is up to the VM to do whatever it
193       * likes with this number; some VMs will ignore it.
194       */
195      private long stackSize;
197      /*
198       * JVM-private state that persists after native thread termination.
199       */
200      private long nativeParkEventPointer;
202      /*
203       * Thread ID
204       */
205      private long tid;
207      /* For generating thread ID */
208      private static long threadSeqNumber;
210      /* Java thread status for tools,
211       * initialized to indicate thread 'not yet started'
212       */
214      private volatile int threadStatus = 0;
217      private static synchronized long nextThreadID() {
218          return ++;
219      }

227      volatile Object parkBlocker;
229      /* The object in which this thread is blocked in an interruptible I/O
230       * operation, if any.  The blocker's interrupt method should be invoked
231       * after setting this thread's interrupt status.
232       */
233      private volatile Interruptible blocker;
234      private final Object blockerLock = new Object();
236      /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
237       */
238      void blockedOn(Interruptible b) {
239          synchronized () {
240               = b;
241          }
242      }

247      public final static int MIN_PRIORITY = 1;

252      public final static int NORM_PRIORITY = 5;

257      public final static int MAX_PRIORITY = 10;

264      public static native Thread currentThread();

282      public static native void yield();

301      public static native void sleep(long millis) throws InterruptedException;

325      public static void sleep(long millis, int nanos)
326      throws InterruptedException {
327          if (millis < 0) {
328              throw new IllegalArgumentException("timeout value is negative");
329          }
331          if (nanos < 0 || nanos > 999999) {
332              throw new IllegalArgumentException(
333                                  "nanosecond timeout value out of range");
334          }
336          if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
337              millis++;
338          }
340          sleep(millis);
341      }

347      private void init(ThreadGroup g, Runnable target, String name,
348                        long stackSize) {
349          init(g, target, name, stackSize, null);
350      }

363      private void init(ThreadGroup g, Runnable target, String name,
364                        long stackSize, AccessControlContext acc) {
365          if (name == null) {
366              throw new NullPointerException("name cannot be null");
367          }
369          Thread parent = currentThread();
370          SecurityManager security = System.getSecurityManager();
371          if (g == null) {
372              /* Determine if it's an applet or not */
374              /* If there is a security manager, ask the security manager
375                 what to do. */
376              if (security != null) {
377                  g = security.getThreadGroup();
378              }
380              /* If the security doesn't have a strong opinion of the matter
381                 use the parent thread group. */
382              if (g == null) {
383                  g = parent.getThreadGroup();
384              }
385          }
387          /* checkAccess regardless of whether or not threadgroup is
388             explicitly passed in. */
389          g.checkAccess();
391          /*
392           * Do we have the required permissions?
393           */
394          if (security != null) {
395              if (isCCLOverridden(getClass())) {
396                  security.checkPermission();
397              }
398          }
400          g.addUnstarted();
402          this. = g;
403          this. = parent.isDaemon();
404          this. = parent.getPriority();
405          this. = name.toCharArray();
406          if (security == null || isCCLOverridden(parent.getClass()))
407              this. = parent.getContextClassLoader();
408          else
409              this. = parent.contextClassLoader;
410          this. =
411                  acc != null ? acc : AccessController.getContext();
412          this. = target;
413          setPriority();
414          if (parent.inheritableThreadLocals != null)
415              this. =
416                  ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
417          /* Stash the specified stack size in case the VM cares */
418          this. = stackSize;
420          /* Set thread ID */
421           = nextThreadID();
422      }

431      @Override
432      protected Object clone() throws CloneNotSupportedException {
433          throw new CloneNotSupportedException();
434      }

443      public Thread() {
444          init(null, null, "Thread-" + nextThreadNum(), 0);
445      }

459      public Thread(Runnable target) {
460          init(null, target, "Thread-" + nextThreadNum(), 0);
461      }

467      Thread(Runnable target, AccessControlContext acc) {
468          init(null, target, "Thread-" + nextThreadNum(), 0, acc);
469      }

494      public Thread(ThreadGroup group, Runnable target) {
495          init(group, target, "Thread-" + nextThreadNum(), 0);
496      }

506      public Thread(String name) {
507          init(null, null, name, 0);
508      }

530      public Thread(ThreadGroup group, String name) {
531          init(group, null, name, 0);
532      }

546      public Thread(Runnable target, String name) {
547          init(null, target, name, 0);
548      }

594      public Thread(ThreadGroup group, Runnable target, String name) {
595          init(group, target, name, 0);
596      }

672      public Thread(ThreadGroup group, Runnable target, String name,
673                    long stackSize) {
674          init(group, target, name, stackSize);
675      }

695      public synchronized void start() {

703          if ( != 0)
704              throw new IllegalThreadStateException();
706          /* Notify the group that this thread is about to be started
707           * so that it can be added to the group's list of threads
708           * and the group's unstarted count can be decremented. */
709          .add(this);
711          boolean started = false;
712          try {
713              start0();
714              started = true;
715          } finally {
716              try {
717                  if (!started) {
718                      .threadStartFailed(this);
719                  }
720              } catch (Throwable ignore) {
721                  /* do nothing. If start0 threw a Throwable then
722                    it will be passed up the call stack */
723              }
724          }
725      }
727      private native void start0();

741      @Override
742      public void run() {
743          if ( != null) {
744              .run();
745          }
746      }

752      private void exit() {
753          if ( != null) {
754              .threadTerminated(this);
755               = null;
756          }
757          /* Aggressively null out all reference fields: see bug 4006245 */
758           = null;
759          /* Speed the release of some of these resources */
760           = null;
761           = null;
762           = null;
763           = null;
764           = null;
765      }

833      @Deprecated
834      public final void stop() {
835          SecurityManager security = System.getSecurityManager();
836          if (security != null) {
837              checkAccess();
838              if (this != Thread.currentThread()) {
839                  security.checkPermission(.);
840              }
841          }
842          // A zero status value corresponds to "NEW", it can't change to
843          // not-NEW because we hold the lock.
844          if ( != 0) {
845              resume(); // Wake up thread if it was suspended; no-op otherwise
846          }
848          // The VM can handle all thread states
849          stop0(new ThreadDeath());
850      }

866      @Deprecated
867      public final synchronized void stop(Throwable obj) {
868          throw new UnsupportedOperationException();
869      }

910      public void interrupt() {
911          if (this != Thread.currentThread())
912              checkAccess();
914          synchronized () {
915              Interruptible b = ;
916              if (b != null) {
917                  interrupt0();           // Just to set the interrupt flag
918                  b.interrupt(this);
919                  return;
920              }
921          }
922          interrupt0();
923      }

942      public static boolean interrupted() {
943          return currentThread().isInterrupted(true);
944      }

959      public boolean isInterrupted() {
960          return isInterrupted(false);
961      }

968      private native boolean isInterrupted(boolean ClearInterrupted);

987      @Deprecated
988      public void destroy() {
989          throw new NoSuchMethodError();
990      }

999      public final native boolean isAlive();

1025      @Deprecated
1026      public final void suspend() {
1027          checkAccess();
1028          suspend0();
1029      }

1051      @Deprecated
1052      public final void resume() {
1053          checkAccess();
1054          resume0();
1055      }

1081      public final void setPriority(int newPriority) {
1082          ThreadGroup g;
1083          checkAccess();
1084          if (newPriority >  || newPriority < ) {
1085              throw new IllegalArgumentException();
1086          }
1087          if((g = getThreadGroup()) != null) {
1088              if (newPriority > g.getMaxPriority()) {
1089                  newPriority = g.getMaxPriority();
1090              }
1091              setPriority0( = newPriority);
1092          }
1093      }

1101      public final int getPriority() {
1102          return ;
1103      }

1119      public final synchronized void setName(String name) {
1120          checkAccess();
1121          this. = name.toCharArray();
1122          if ( != 0) {
1123              setNativeName(name);
1124          }
1125      }

1133      public final String getName() {
1134          return new String(, true);
1135      }

1144      public final ThreadGroup getThreadGroup() {
1145          return ;
1146      }

1164      public static int activeCount() {
1165          return currentThread().getThreadGroup().activeCount();
1166      }

1194      public static int enumerate(Thread tarray[]) {
1195          return currentThread().getThreadGroup().enumerate(tarray);
1196      }

1209      @Deprecated
1210      public native int countStackFrames();

1233      public final synchronized void join(long millis)
1234      throws InterruptedException {
1235          long base = System.currentTimeMillis();
1236          long now = 0;
1238          if (millis < 0) {
1239              throw new IllegalArgumentException("timeout value is negative");
1240          }
1242          if (millis == 0) {
1243              while (isAlive()) {
1244                  wait(0);
1245              }
1246          } else {
1247              while (isAlive()) {
1248                  long delay = millis - now;
1249                  if (delay <= 0) {
1250                      break;
1251                  }
1252                  wait(delay);
1253                  now = System.currentTimeMillis() - base;
1254              }
1255          }
1256      }

1283      public final synchronized void join(long millis, int nanos)
1284      throws InterruptedException {
1286          if (millis < 0) {
1287              throw new IllegalArgumentException("timeout value is negative");
1288          }
1290          if (nanos < 0 || nanos > 999999) {
1291              throw new IllegalArgumentException(
1292                                  "nanosecond timeout value out of range");
1293          }
1295          if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
1296              millis++;
1297          }
1299          join(millis);
1300      }

1317      public final void join() throws InterruptedException {
1318          join(0);
1319      }

1327      public static void dumpStack() {
1328          new Exception("Stack trace").printStackTrace();
1329      }

1348      public final void setDaemon(boolean on) {
1349          checkAccess();
1350          if (isAlive()) {
1351              throw new IllegalThreadStateException();
1352          }
1353           = on;
1354      }

1363      public final boolean isDaemon() {
1364          return ;
1365      }

1379      public final void checkAccess() {
1380          SecurityManager security = System.getSecurityManager();
1381          if (security != null) {
1382              security.checkAccess(this);
1383          }
1384      }

1392      public String toString() {
1393          ThreadGroup group = getThreadGroup();
1394          if (group != null) {
1395              return "Thread[" + getName() + "," + getPriority() + "," +
1396                             group.getName() + "]";
1397          } else {
1398              return "Thread[" + getName() + "," + getPriority() + "," +
1399                              "" + "]";
1400          }
1401      }

1429      @CallerSensitive
1430      public ClassLoader getContextClassLoader() {
1431          if ( == null)
1432              return null;
1433          SecurityManager sm = System.getSecurityManager();
1434          if (sm != null) {
1435              ClassLoader.checkClassLoaderPermission(,
1436                                                     Reflection.getCallerClass());
1437          }
1438          return ;
1439      }

1463      public void setContextClassLoader(ClassLoader cl) {
1464          SecurityManager sm = System.getSecurityManager();
1465          if (sm != null) {
1466              sm.checkPermission(new RuntimePermission("setContextClassLoader"));
1467          }
1468           = cl;
1469      }

1487      public static native boolean holdsLock(Object obj);
1489      private static final StackTraceElement[] EMPTY_STACK_TRACE
1490          = new StackTraceElement[0];

1528      public StackTraceElement[] getStackTrace() {
1529          if (this != Thread.currentThread()) {
1530              // check for getStackTrace permission
1531              SecurityManager security = System.getSecurityManager();
1532              if (security != null) {
1533                  security.checkPermission(
1534                      .);
1535              }
1536              // optimization so we do not call into the vm for threads that
1537              // have not yet started or have terminated
1538              if (!isAlive()) {
1539                  return ;
1540              }
1541              StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
1542              StackTraceElement[] stackTrace = stackTraceArray[0];
1543              // a thread that was alive during the previous isAlive call may have
1544              // since terminated, therefore not having a stacktrace.
1545              if (stackTrace == null) {
1546                  stackTrace = ;
1547              }
1548              return stackTrace;
1549          } else {
1550              // Don't need JVM help for current thread
1551              return (new Exception()).getStackTrace();
1552          }
1553      }

1590      public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
1591          // check for getStackTrace permission
1592          SecurityManager security = System.getSecurityManager();
1593          if (security != null) {
1594              security.checkPermission(
1595                  .);
1596              security.checkPermission(
1597                  .);
1598          }
1600          // Get a snapshot of the list of all threads
1601          Thread[] threads = getThreads();
1602          StackTraceElement[][] traces = dumpThreads(threads);
1603          Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
1604          for (int i = 0; i < threads.length; i++) {
1605              StackTraceElement[] stackTrace = traces[i];
1606              if (stackTrace != null) {
1607                  m.put(threads[i], stackTrace);
1608              }
1609              // else terminated so we don't put it in the map
1610          }
1611          return m;
1612      }
1615      private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
1616                      new RuntimePermission("enableContextClassLoaderOverride");

1619      /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
1620       * release */
1621      private static class Caches {

1623          static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
1624              new ConcurrentHashMap<>();

1627          static final ReferenceQueue<Class<?>> subclassAuditsQueue =
1628              new ReferenceQueue<>();
1629      }

1637      private static boolean isCCLOverridden(Class<?> cl) {
1638          if (cl == Thread.class)
1639              return false;
1641          processQueue(., .);
1642          WeakClassKey key = new WeakClassKey(cl, .);
1643          Boolean result = ..get(key);
1644          if (result == null) {
1645              result = Boolean.valueOf(auditSubclass(cl));
1646              ..putIfAbsent(key, result);
1647          }
1649          return result.booleanValue();
1650      }

1657      private static boolean auditSubclass(final Class<?> subcl) {
1658          Boolean result = AccessController.doPrivileged(
1659              new PrivilegedAction<Boolean>() {
1660                  public Boolean run() {
1661                      for (Class<?> cl = subcl;
1662                           cl != Thread.class;
1663                           cl = cl.getSuperclass())
1664                      {
1665                          try {
1666                              cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
1667                              return .;
1668                          } catch (NoSuchMethodException ex) {
1669                          }
1670                          try {
1671                              Class<?>[] params = {ClassLoader.class};
1672                              cl.getDeclaredMethod("setContextClassLoader", params);
1673                              return .;
1674                          } catch (NoSuchMethodException ex) {
1675                          }
1676                      }
1677                      return .;
1678                  }
1679              }
1680          );
1681          return result.booleanValue();
1682      }
1684      private native static StackTraceElement[][] dumpThreads(Thread[] threads);
1685      private native static Thread[] getThreads();

1696      public long getId() {
1697          return ;
1698      }

1734      public enum State {

1738          NEW,

1746          RUNNABLE,

1755          BLOCKED,

1776          WAITING,

1790          TIMED_WAITING,

1796          TERMINATED;
1797      }

1807      public State getState() {
1808          // get current thread state
1809          return sun.misc.VM.toThreadState();
1810      }
1812      // Added in JSR-166
1813  

1836      @FunctionalInterface
1837      public interface UncaughtExceptionHandler {

1846          void uncaughtException(Thread t, Throwable e);
1847      }
1849      // null unless explicitly set
1850      private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
1852      // null unless explicitly set
1853      private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;

1889      public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
1890          SecurityManager sm = System.getSecurityManager();
1891          if (sm != null) {
1892              sm.checkPermission(
1893                  new RuntimePermission("setDefaultUncaughtExceptionHandler")
1894                      );
1895          }
1897            = eh;
1898       }

1908      public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
1909          return ;
1910      }

1921      public UncaughtExceptionHandler getUncaughtExceptionHandler() {
1922          return  != null ?
1923               : ;
1924      }

1941      public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
1942          checkAccess();
1943           = eh;
1944      }

1950      private void dispatchUncaughtException(Throwable e) {
1951          getUncaughtExceptionHandler().uncaughtException(this, e);
1952      }

1958      static void processQueue(ReferenceQueue<Class<?>> queue,
1959                               ConcurrentMap<? extends
1960                               WeakReference<Class<?>>, ?> map)
1961      {
1962          Reference<? extends Class<?>> ref;
1963          while((ref = queue.poll()) != null) {
1964              map.remove(ref);
1965          }
1966      }

1971      static class WeakClassKey extends WeakReference<Class<?>> {

1976          private final int hash;

1982          WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
1983              super(cl, refQueue);
1984               = System.identityHashCode(cl);
1985          }

1990          @Override
1991          public int hashCode() {
1992              return ;
1993          }

2001          @Override
2002          public boolean equals(Object obj) {
2003              if (obj == this)
2004                  return true;
2006              if (obj instanceof WeakClassKey) {
2007                  Object referent = get();
2008                  return (referent != null) &&
2009                         (referent == ((WeakClassKey) obj).get());
2010              } else {
2011                  return false;
2012              }
2013          }
2014      }
2017      // The following three initially uninitialized fields are exclusively
2018      // managed by class java.util.concurrent.ThreadLocalRandom. These
2019      // fields are used to build the high-performance PRNGs in the
2020      // concurrent code, and we can not risk accidental false sharing.
2021      // Hence, the fields are isolated with @Contended.
2022  

2024      @sun.misc.Contended("tlr")
2025      long threadLocalRandomSeed;

2028      @sun.misc.Contended("tlr")
2029      int threadLocalRandomProbe;

2032      @sun.misc.Contended("tlr")
2033      int threadLocalRandomSecondarySeed;
2035      /* Some private helper methods */
2036      private native void setPriority0(int newPriority);
2037      private native void stop0(Object o);
2038      private native void suspend0();
2039      private native void resume0();
2040      private native void interrupt0();
2041      private native void setNativeName(String name);
2042  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的线程是通过Thread类来实现的,Thread类封装了所有线程相关的方法和属性。下面是Thread类的部分源码: ```java public class Thread implements Runnable { //线程状态 private volatile int threadStatus = 0; private static final int RUNNING = 1; private static final int SHUTDOWN = -1; private static final int STOP = -2; private static final int TIDYING = 2; private static final int TERMINATED = 3; //线程优先级 public final static int MIN_PRIORITY = 1; public final static int NORM_PRIORITY = 5; public final static int MAX_PRIORITY = 10; //线程组 private ThreadGroup group; private Runnable target; private String name; private long stackSize; private long eetop; //线程ID private long tid; //线程本地存储 ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; //线程中断标志 private volatile boolean interrupted = false; private static final int HIBERNATE = 0; private static final int WAITING = 1; private static final int TIMED_WAITING = 2; private static final int BLOCKED = 3; private static final int NEW = 0; //线程锁 private Object parkBlocker; //线程中断处理 private void handleInterrupt() { if (this != Thread.currentThread()) throw new RuntimeException("Only the original thread can be interrupted"); if (this.interrupted) { park(); } } //线程休眠 public static void sleep(long millis) throws InterruptedException { Thread.sleep(millis, 0); } //中断线程 public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (this) { interrupted = true; notifyAll(); } } //线程运行方法 @Override public void run() { if (target != null) { target.run(); } } } ``` 在Thread类中,我们可以看到一些重要的属性和方法,比如: - threadStatus: 线程状态,用整数表示,包含RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED五种状态。 - group: 线程所属的线程组。 - target: 线程要执行的任务。 - name: 线程名称。 - stackSize: 线程堆栈大小。 - tid: 线程ID。 - threadLocals: 线程本地存储。 - interrupted: 线程中断标志。 - parkBlocker: 线程锁。 - sleep(): 线程休眠方法。 - interrupt(): 中断线程方法。 - run(): 线程运行方法。 通过这些属性和方法,我们可以使用Java中的线程实现多线程编程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值