Thread 源码

6 篇文章 0 订阅

创建线程方式

有2种方式可以创建一个可执行线程。

1.继承Thread类。子类可覆写父类的run()方法。子类实例分配内存后可运行(非立即,取决于CPU调用)
  
class PrimeThread extends Thread {
     
     long minPrime;
     PrimeThread(long minPrime) {
          this.minPrime = minPrime;
     }

     public void run() {
         // compute primes larger than minPrime
         ...
     }
}

启动
PrimeThread p = new PrimeThread(143);
p.start();

2.实现Runnable接口。
  此类自己会实现run()方法。然后此线程会被分配内存,当线程被创建时,会传入一个参数,然后开始执行。

class PrimeRun implements Runnable {
     long minPrime;
     PrimeRun(long minPrime) {
          this.minPrime = minPrime;
      }

      public void run() {
          // compute primes larger than minPrime
          ...
      }
}

启动
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

线程状态转换

在这里插入图片描述

继承关系

在这里插入图片描述

源码

public
class Thread implements Runnable {
    /**
     * 确保本地注册(类构造器方法<clinit>方法用于类初始化)是创建线程首先做的事情
     */
    private static native void registerNatives();

    static {
        registerNatives();
    }

    /**
     * 线程名
     */
    private volatile String name;
    /**
     * 线程优先级,int 表示
     */
    private int priority;
    private Thread threadQ;
    private long eetop;

    private boolean single_step;

    /**
     * 是否是守护线程
     * 当所有非守护进程结束或死亡后,程序将停止
     */
    private boolean daemon = false;

    /**
     * JVM状态
     */
    private boolean stillborn = false;

    /**
     * run方法执行的目标代码
     */
    private Runnable target;

    /**
     * 所属线程组
     */
    private ThreadGroup group;

    /**
     * 此类型的类加载器
     */
    private ClassLoader contextClassLoader;

    /**
     * 此线程继承的访问控制上下文
     */
    private AccessControlContext inheritedAccessControlContext;

    /**
     * 用于自动编号的匿名线程
     */
    private static int threadInitNumber;

    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }

    /**
     * 此线程的本地变量值
     * 此map由ThreadLocal类进行维护,因为这个类在ThreadLocal中是包级私有的
     */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /**
     * 和此线程相关的由继承得到的本地变量值
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

    /**
     * 此线程请求栈的深度,如果线程创建者未指定栈深度则其值为0
     * 此数字如何被使用完全取决于虚拟机自己;也有一些虚拟机会忽略此变量值
     */
    private long stackSize;

    /**
     * 此变量表示:在本地线程终止后,JVM私有的一个状态值
     */
    private long nativeParkEventPointer;

    /**
     * 线程id
     */
    private long tid;

    /**
     * 用于生成线程ID
     */
    private static long threadSeqNumber;

    /**
     * 线程状态值,初始化值表示当前线程还未运行
     */
    private volatile int threadStatus = 0;

    /**
     * 获取下一个线程id
     */
    private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }

    /**
     * 用于调用 java.util.concurrent.locks.LockSupport.park方法的参数
     */
    volatile Object parkBlocker;

    /**
     * 如果此线程状态被设置为中断状态,则调用此阻塞对象的中断方法
     */
    private volatile Interruptible blocker;
    private final Object blockerLock = new Object();

    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }

    /**
     * 线程可以拥有的最低优先级
     */
    public final static int MIN_PRIORITY = 1;

    /**
     * 线程的默认优先级
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * 线程可以拥有的最高优先级
     */
    public final static int MAX_PRIORITY = 10;

    /**
     * 返回当前线程对象的引用
     */
    public static native Thread currentThread();

    /**
     * 提示线程调度器当前线程愿意放弃当前CPU的使用
     * <p>
     * 让出CPU是一种启发式的尝试,以改善线程之间的相对进展,否则将过度利用CPU
     * 此方法很少有适用的场景。当设计并发控制结构(如java.util.concurrent.locks包中的并发结构)时,它可能比较有用
     */
    public static native void yield();

    /**
     * 此方法会引起当前执行线程sleep(临时停止执行)指定毫秒数
     * 此方法的调用不会引起当前线程放弃任何监听器(monitor)的所有权(ownership)
     */
    public static native void sleep(long millis) throws InterruptedException;

    /**
     * 同 sleep(long millis)
     */
    public static void sleep(long millis, int nanos)
            throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }

    /**
     * 初始化一个线程
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }

    /**
     * 初始化一个线程
     *
     * @param g                   线程分组
     * @param target              run() 方法执行代码
     * @param name                线程名
     * @param stackSize           值为0表示此参数被忽略
     * @param acc                 用于继承的访问控制上下文
     * @param inheritThreadLocals 如果值为true,从构造线程继承可继承线程局部变量的初始值
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        // 获取线程组
        if (g == null) {
            // 从SecurityManager拿线程组
            if (security != null) {
                g = security.getThreadGroup();
            }

            // 如果还没拿到从当前线程拿
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        // 检查是否可获取
        g.checkAccess();

        // 检查是否有required权限
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        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)
            this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        this.stackSize = stackSize;

        // 设置线程ID
        tid = nextThreadID();
    }

    /**
     * 线程不支持前拷贝,抛异常
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    /**
     * 无参构造函数,默认线程名随机
     */
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 构造函数,指定执行对象
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 构造函数,指定执行对象和上下文
     */
    Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
    }

    /**
     * 构造函数,指定线程组和执行对象
     */
    public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }

    /**
     * 构造函数,指定线程名
     */
    public Thread(String name) {
        init(null, null, name, 0);
    }

    /**
     * 构造函数,指定线程组和线程名
     */
    public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }

    /**
     * 构造函数,指定执行代码和线程名
     */
    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }

    /**
     * 构造函数,指定线程组、执行代码和线程名
     */
    public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }

    /**
     * 构造函数,指定线程组、执行代码和线程名
     */
    public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
        init(group, target, name, stackSize);
    }

    /**
     * 执行当前线程,JVM会调用此线程的run()方法
     * 就是说当调用该方法后有两个线程并发执行:当前线程(从调用的start方法返回)和另一个线程(它在执行run方法)
     * 多次start一个线程会
     *
     * @throws IllegalThreadStateException 多次start一个线程会
     */
    public synchronized void start() {
        // //状态校验  0:NEW 新建状态
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        // 添加进线程组
        group.add(this);

        boolean started = false;
        try {
            // 调用native方法执行线程run方法
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    // 启动失败,从线程组中移除当前前程
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            }
        }
    }

    private native void start0();

    /**
     * 如果此线程有runable对象,则执行,否则什么也不执行
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

    /**
     * 此方法由系统调用,可以使Thread在销毁前释放资源
     */
    private void exit() {
        if (group != null) {
            // 移除线程
            group.threadTerminated(this);
            group = null;
        }
        target = null;
        threadLocals = null;
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }

    @Deprecated
    public final void stop() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        if (threadStatus != 0) {
            resume();
        }

        stop0(new ThreadDeath());
    }

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

    /**
     * 中断当前线程
     *
     * <p> Unless the current thread is interrupting itself, which is
     * always permitted, the {@link #checkAccess() checkAccess} method
     * of this thread is invoked, which may cause a {@link
     * SecurityException} to be thrown.
     *
     * <p> If this thread is blocked in an invocation of the {@link
     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
     * class, or of the {@link #join()}, {@link #join(long)}, {@link
     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
     * methods of this class, then its interrupt status will be cleared and it
     * will receive an {@link InterruptedException}.
     *
     * <p> If this thread is blocked in an I/O operation upon an {@link
     * java.nio.channels.InterruptibleChannel InterruptibleChannel}
     * then the channel will be closed, the thread's interrupt
     * status will be set, and the thread will receive a {@link
     * java.nio.channels.ClosedByInterruptException}.
     *
     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
     * then the thread's interrupt status will be set and it will return
     * immediately from the selection operation, possibly with a non-zero
     * value, just as if the selector's {@link
     * java.nio.channels.Selector#wakeup wakeup} method were invoked.
     *
     * <p> If none of the previous conditions hold then this thread's interrupt
     * status will be set. </p>
     *
     * <p> Interrupting a thread that is not alive need not have any effect.
     *
     * @throws SecurityException if the current thread cannot modify this thread
     * @revised 6.0
     * @spec JSR-51
     */

    /**
     * 中断当前线程
     * <p>
     * 除非当前线程在中断自己,否则checkAccess()方法抛出异常SecurityException
     * <p>
     * 1.如果当前线程由于wait类型方法,join类型方法或者sleep类型的方法的调用被阻塞,则它的中断状态将被清除且会收到一个
     * 中断异常InterruptedException
     * <p>
     * 2.如果此线程由于java.nio.channels.InterruptibleChannel类中的InterruptibleChannel的I/O操作而被阻塞,
     * 则此方法会导致通道被关闭,且线程的中断状态会被重置,同时线程会收到一个异常ClosedByInterruptException。
     * <p>
     * 3.如果此线程由于java.nio.channels.Selector而阻塞,则线程的中断状态会被重置,且它将立即从阻塞的selection操作返回,
     * 且返回值通常是一个非零值,这就和java.nio.channels.Selector#wakeup的wakeup()方法被调用一样。
     * <p>
     * 4.如果前面的条件都不成立,那么该线程的中断状态将被重置。
     * <p>
     * 中断一个处于非活着状态的线程并不需要产生任何其它影响
     **/
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        // 对阻塞锁使用同步机制
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // 只是为了设定中断标识位
                b.interrupt(this); // 中断当前线程
                return;
            }
        }
        interrupt0(); // 只是为了设定中断标识位
    }

    /**
     * 返回当前线程中断状态,调用方法后线程中断状态会被清除
     * 也就是调用两次,第二次会返回false
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

    /**
     * 返回当前线程中断状态,调用方法后线程中断状态不会被清除
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * 返回当前线程中断状态
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

    @Deprecated
    public void destroy() {
        throw new NoSuchMethodError();
    }

    /**
     * 返回当前线程是否处于存活状态,在死亡状态前都是存活状态
     */
    public final native boolean isAlive();

    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }

    @Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }

    /**
     * 设置线程优先级
     */
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        // 要求线程必须有所属线程组
        if ((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }

    /**
     * 获取线程状态优先级
     */
    public final int getPriority() {
        return priority;
    }

    /**
     * 设置线程名
     */
    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);
        }
    }

    /**
     * 返回线程名
     */
    public final String getName() {
        return name;
    }

    /**
     * 返回所属线程组
     */
    public final ThreadGroup getThreadGroup() {
        return group;
    }

    /**
     * 返回所属线程组的线程数
     */
    public static int activeCount() {
        return currentThread().getThreadGroup().activeCount();
    }

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

    @Deprecated
    public native int countStackFrames();

    /**
     * 最多等待参数millis(ms)时长当前线程就会死亡。参数为0时则要持续等待
     * <p>
     * 此方法在实现上:循环调用wait()方法,当线程终止时notifyAll()方法会被调用
     * 建议应用程序不要在线程实例上使用wait,notify,notifyAll方法.
     */
    public final synchronized void join(long millis)
            throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        // 如果等待时间<0,则抛出异常
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            // 等待时间为0
            while (isAlive()) {
                wait(0);
            }
        } else {
            // 指定等待时间
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    // 超时返回
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

    /**
     * 同 join(long millis)
     */
    public final synchronized void join(long millis, int nanos)
            throws InterruptedException {

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        join(millis);
    }

    /**
     * 一直等待到线程死亡
     */
    public final void join() throws InterruptedException {
        join(0);
    }

    /**
     * 打印栈异常信息
     */
    public static void dumpStack() {
        new Exception("Stack trace").printStackTrace();
    }

    /**
     * 将当前线程设定为守护线程,此方法在start前被调用
     */
    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }

    /**
     * 返回是否守护线程
     */
    public final boolean isDaemon() {
        return daemon;
    }

    /**
     * 判断当前运行的线程是否有权利更改此线程
     */
    public final void checkAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkAccess(this);
        }
    }

    /**
     * 格式包括 :线程名+优先级+所属组别
     */
    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    "" + "]";
        }
    }

    /**
     * 返回此线程的上下文类加载器
     */
    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                    Reflection.getCallerClass());
        }
        return contextClassLoader;
    }

    /**
     * 设置此线程的上下文类加载器
     */
    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }

    /**
     * 当且仅当当前线程持有指定对象的监听器锁时,返回返回true
     */
    public static native boolean holdsLock(Object obj);

    private static final StackTraceElement[] EMPTY_STACK_TRACE
            = new StackTraceElement[0];

    /**
     * 返回表示该线程堆栈转储的堆栈跟踪元素数组
     */
    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            // check for getStackTrace permission
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkPermission(
                        SecurityConstants.GET_STACK_TRACE_PERMISSION);
            }
            // optimization so we do not call into the vm for threads that
            // have not yet started or have terminated
            if (!isAlive()) {
                return EMPTY_STACK_TRACE;
            }
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]{this});
            StackTraceElement[] stackTrace = stackTraceArray[0];
            // a thread that was alive during the previous isAlive call may have
            // since terminated, therefore not having a stacktrace.
            if (stackTrace == null) {
                stackTrace = EMPTY_STACK_TRACE;
            }
            return stackTrace;
        } else {
            // Don't need JVM help for current thread
            return (new Exception()).getStackTrace();
        }
    }

    /**
     * 返回一个所有存活线程的栈跟踪信息的Map
     */
    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
            security.checkPermission(
                    SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
        }

        // Get a snapshot of the list of all threads
        Thread[] threads = getThreads();
        StackTraceElement[][] traces = dumpThreads(threads);
        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
        for (int i = 0; i < threads.length; i++) {
            StackTraceElement[] stackTrace = traces[i];
            if (stackTrace != null) {
                m.put(threads[i], stackTrace);
            }
            // else terminated so we don't put it in the map
        }
        return m;
    }


    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
            new RuntimePermission("enableContextClassLoaderOverride");

    /**
     * 子类安全审核结果的缓存
     */
    private static class Caches {
        /**
         * cache of subclass security audit results
         */
        static final ConcurrentMap<Thread.WeakClassKey, Boolean> subclassAudits =
                new ConcurrentHashMap<>();

        /**
         * queue for WeakReferences to audited subclasses
         */
        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
                new ReferenceQueue<>();
    }

    /**
     * Verifies that this (possibly subclass) instance can be constructed
     * without violating security constraints: the subclass must not override
     * security-sensitive non-final methods, or else the
     * "enableContextClassLoaderOverride" RuntimePermission is checked.
     */
    private static boolean isCCLOverridden(Class<?> cl) {
        if (cl == Thread.class)
            return false;

        processQueue(Caches.subclassAuditsQueue, Thread.Caches.subclassAudits);
        Thread.WeakClassKey key = new Thread.WeakClassKey(cl, Thread.Caches.subclassAuditsQueue);
        Boolean result = Thread.Caches.subclassAudits.get(key);
        if (result == null) {
            result = Boolean.valueOf(auditSubclass(cl));
            Thread.Caches.subclassAudits.putIfAbsent(key, result);
        }

        return result.booleanValue();
    }

    /**
     * Performs reflective checks on given subclass to verify that it doesn't
     * override security-sensitive non-final methods.  Returns true if the
     * subclass overrides any of the methods, false otherwise.
     */
    private static boolean auditSubclass(final Class<?> subcl) {
        Boolean result = AccessController.doPrivileged(
                new PrivilegedAction<Boolean>() {
                    public Boolean run() {
                        for (Class<?> cl = subcl;
                             cl != Thread.class;
                             cl = cl.getSuperclass()) {
                            try {
                                cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                            try {
                                Class<?>[] params = {ClassLoader.class};
                                cl.getDeclaredMethod("setContextClassLoader", params);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                        }
                        return Boolean.FALSE;
                    }
                }
        );
        return result.booleanValue();
    }

    private native static StackTraceElement[][] dumpThreads(Thread[] threads);

    private native static Thread[] getThreads();

    /**
     * 返回当前线程ID
     */
    public long getId() {
        return tid;
    }


    /**
     * 表示线程状态。有如下几种:
     * 1.NEW:表示:线程还未开始,只是进行了一些线程创建的初始化操作,但未调用start()方法
     * 2.RUNNABLE:线程在JVM里面处于运行状态(这里就绪和运行同属于运行)
     * 3.BLOCKED:线程正在等待一个监视器锁,处于阻塞状态
     * 4.WAITING:一个线程在等待另一个线程的特定操作(通知or中断),这种等待是无限期的
     * 5.TIMED_WAITING:一个线程在等待另一个线程的特定操作,这种等待是有时间限制的。一旦超时则线程自行返回
     * 6.TERMINATED:线程已退出.表示线程已经执行完毕
     * <p>
     * 线程在某一时刻,只能处于上述6个状态的某一个。这些状态值是虚拟机状态值,因而并不会反映操作系统的线程状态。
     */
    public enum State {
        NEW,

        /**
         * 线程可以正在运行,也可以处于就绪状态等待获得CPU
         */
        RUNNABLE,

        /**
         * 在调用完wait()方法后进入
         */
        BLOCKED,

        /**
         * 一个线程处于wating状态,是因为调用了下面方法中的某一个:
         * 1.Object.wait
         * 2.Thread.join
         * 3.LockSupport.park
         * <p>
         * 其它线程的特定操作包括 :notify(),notifyAll(),join()等.
         */
        WAITING,

        /**
         * 线程等待指定时间.
         * 这种状态的出现是因为调用了下面方法中的某一个:
         * 1.Thread.sleep()
         * 2.Object.wait()
         * 3.Thread.join()
         * 4.LockSupport.parkNanos()
         * 5.LockSupport.parkUntil()
         */
        TIMED_WAITING,

        TERMINATED;
    }

    /**
     * 返回线程状态
     */
    public Thread.State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }

    // Added in JSR-166

    /**
     * Interface for handlers invoked when a <tt>Thread</tt> 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
     * <tt>UncaughtExceptionHandler</tt> using
     * {@link #getUncaughtExceptionHandler} and will invoke the handler's
     * <tt>uncaughtException</tt> method, passing the thread and the
     * exception as arguments.
     * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
     * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
     * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
     * has no
     * special requirements for dealing with the exception, it can forward
     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
     * default uncaught exception handler}.
     *
     * @see #setDefaultUncaughtExceptionHandler
     * @see #setUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         *
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }

    // null unless explicitly set
    private volatile Thread.UncaughtExceptionHandler uncaughtExceptionHandler;

    // null unless explicitly set
    private static volatile Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler;

    /**
     * Set the default handler invoked when a thread abruptly terminates
     * due to an uncaught exception, and no other handler has been defined
     * for that thread.
     *
     * <p>Uncaught exception handling is controlled first by the thread, then
     * by the thread's {@link ThreadGroup} object and finally by the default
     * uncaught exception handler. If the thread does not have an explicit
     * uncaught exception handler set, and the thread's thread group
     * (including parent thread groups)  does not specialize its
     * <tt>uncaughtException</tt> method, then the default handler's
     * <tt>uncaughtException</tt> method will be invoked.
     * <p>By setting the default uncaught exception handler, an application
     * can change the way in which uncaught exceptions are handled (such as
     * logging to a specific device, or file) for those threads that would
     * already accept whatever &quot;default&quot; behavior the system
     * provided.
     *
     * <p>Note that the default uncaught exception handler should not usually
     * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
     * infinite recursion.
     *
     * @param eh the object to use as the default uncaught exception handler.
     *           If <tt>null</tt> then there is no default handler.
     * @throws SecurityException if a security manager is present and it
     *                           denies <tt>{@link RuntimePermission}
     *                           (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
     * @see #setUncaughtExceptionHandler
     * @see #getUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                    new RuntimePermission("setDefaultUncaughtExceptionHandler")
            );
        }

        defaultUncaughtExceptionHandler = eh;
    }

    /**
     * Returns the default handler invoked when a thread abruptly terminates
     * due to an uncaught exception. If the returned value is <tt>null</tt>,
     * there is no default.
     *
     * @return the default uncaught exception handler for all threads
     * @see #setDefaultUncaughtExceptionHandler
     * @since 1.5
     */
    public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
        return defaultUncaughtExceptionHandler;
    }

    /**
     * Returns the handler invoked when this thread abruptly terminates
     * due to an uncaught exception. If this thread has not had an
     * uncaught exception handler explicitly set then this thread's
     * <tt>ThreadGroup</tt> object is returned, unless this thread
     * has terminated, in which case <tt>null</tt> is returned.
     *
     * @return the uncaught exception handler for this thread
     * @since 1.5
     */
    public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
                uncaughtExceptionHandler : group;
    }

    /**
     * Set the handler invoked when this thread abruptly terminates
     * due to an uncaught exception.
     * <p>A thread can take full control of how it responds to uncaught
     * exceptions by having its uncaught exception handler explicitly set.
     * If no such handler is set then the thread's <tt>ThreadGroup</tt>
     * object acts as its handler.
     *
     * @param eh the object to use as this thread's uncaught exception
     *           handler. If <tt>null</tt> then this thread has no explicit handler.
     * @throws SecurityException if the current thread is not allowed to
     *                           modify this thread.
     * @see #setDefaultUncaughtExceptionHandler
     * @see ThreadGroup#uncaughtException
     * @since 1.5
     */
    public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) {
        checkAccess();
        uncaughtExceptionHandler = eh;
    }

    /**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }

    /**
     * Removes from the specified map any keys that have been enqueued
     * on the specified reference queue.
     */
    static void processQueue(ReferenceQueue<Class<?>> queue,
                             ConcurrentMap<? extends
                                     WeakReference<Class<?>>, ?> map) {
        Reference<? extends Class<?>> ref;
        while ((ref = queue.poll()) != null) {
            map.remove(ref);
        }
    }

    /**
     * Weak key for Class objects.
     **/
    static class WeakClassKey extends WeakReference<Class<?>> {
        /**
         * saved value of the referent's identity hash code, to maintain
         * a consistent hash code after the referent has been cleared
         */
        private final int hash;

        /**
         * Create a new WeakClassKey to the given object, registered
         * with a queue.
         */
        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
            super(cl, refQueue);
            hash = System.identityHashCode(cl);
        }

        /**
         * Returns the identity hash code of the original referent.
         */
        @Override
        public int hashCode() {
            return hash;
        }

        /**
         * Returns true if the given object is this identical
         * WeakClassKey instance, or, if this object's referent has not
         * been cleared, if the given object is another WeakClassKey
         * instance with the identical non-null referent as this one.
         */
        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (obj instanceof Thread.WeakClassKey) {
                Object referent = get();
                return (referent != null) &&
                        (referent == ((Thread.WeakClassKey) obj).get());
            } else {
                return false;
            }
        }
    }


    // The following three initially uninitialized fields are exclusively
    // managed by class java.util.concurrent.ThreadLocalRandom. These
    // fields are used to build the high-performance PRNGs in the
    // concurrent code, and we can not risk accidental false sharing.
    // Hence, the fields are isolated with @Contended.

    /**
     * The current seed for a ThreadLocalRandom
     */
    @sun.misc.Contended("tlr")
    long threadLocalRandomSeed;

    /**
     * Probe hash value; nonzero if threadLocalRandomSeed initialized
     */
    @sun.misc.Contended("tlr")
    int threadLocalRandomProbe;

    /**
     * Secondary seed isolated from public ThreadLocalRandom sequence
     */
    @sun.misc.Contended("tlr")
    int threadLocalRandomSecondarySeed;

    /**
     * 一些私有本地辅助方法
     */
    private native void setPriority0(int newPriority);

    private native void stop0(Object o);

    private native void suspend0();

    private native void resume0();

    private native void interrupt0();

    private native void setNativeName(String name);
}
注意点

每个线程都有一个用于目的标识的名字。多个线程可以有相同的名字。线程被创建时如果名字没有被指定,则系统为其自动生成一个新的名字。

多次调用start方法会报异常 IllegalThreadStateException。

最低优先级为1,默认优先级为5,最高优先级为10。

ThreadGroup 并不能提供对线程的管理,主要功能是对线程进行组织,创建线程的时候如果没有显式的指定 ThreadGroup,那么新的线程将会默认加入与父线程相同的线程组中。

参考 https://blog.csdn.net/caoxiaohong1005/article/details/80312396

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值