java Thread 类的源码阅读(oracle jdk1.8)

Posted zhangshiwen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Thread 类的源码阅读(oracle jdk1.8)相关的知识,希望对你有一定的参考价值。

java线程类的源码分析阅读技巧;

首先阅读thread类重点关注一下几个问题;

1、start() ,启动一个线程是如何实现的?

2、java线程状态机的变化过程以及如何实现的?


 

1、start方法的源码如下:

new Thread(Runnable);代码内部实际代码如下:

技术图片
    /**
     * Initializes a Thread.
     *
     * @param g the Thread group
     * @param target the object whose run() method gets called
     * @param name the name of the new Thread
     * @param stackSize the desired stack size for the new thread, or
     *        zero to indicate that this parameter is to be ignored.
     * @param acc the AccessControlContext to inherit, or
     *            AccessController.getContext() if null
     * @param inheritThreadLocals if {@code true}, inherit initial values for
     *            inheritable thread-locals from the constructing thread
     */
    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) {
            /* Determine if it‘s an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn‘t have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();

        /*
         * Do we have the required permissions?
         */
        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);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }
View Code

然后看start方法代码如下:

 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group‘s list of threads
         * and the group‘s unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

由此可见start方法的本质是调用本地方法start0()即进行的系统调用;

 

2、java线程的状态机的变化情况:重点关注 Thread中的一个静态枚举内部类,State  和Thread中的一个变量 threadStatus 的变化

threadStatus代码如下:

  /* Java thread status for tools,
     * initialized to indicate thread ‘not yet started‘
     */

    private volatile int threadStatus = 0;

但是奇怪的是发现在Thread类中并没有对threadStatus进行过赋值。又见网友分析,java的状态变化存在c++中。例如native start0()方法等。

 

以上是关于java Thread 类的源码阅读(oracle jdk1.8)的主要内容,如果未能解决你的问题,请参考以下文章

我的jdk源码:Thread类

Java Thread.join()详解--父线程等待子线程结束后再结束

源码分析:Java中的Thread的创建和运行

Thread 源码阅读

一脚踩进java之基础篇43——线程Thread和Runnable

一脚踩进java之基础篇43——线程Thread和Runnable