zoukankan      html  css  js  c++  java
  • 线程的start方法解析

    Thread是学习我们学习多线程接触到的第一个有关多线程的类,相信每一个学习过或者了解过Java多线程的小伙伴都知道Thread类。这次分享主要对Thread的start方法进行讲解。

    相信大家都知道,start方法是启动一个线程,并且该线程进入了可执行状态。在实际的编码中,我们是重写run()方法,调用start()方法启动线程,那么run()和start()方法有什么联系呢?下面我们就详细说说。

    一、源码分析

    首先我们查看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 */
                }
            }
        }
    

    start()方法是非常简单的,如果从上面单独看上面源码是看不出任何端倪的,不过我们可以看出来Thread被创建之后,threadStatus这个内部属性的值是0 。在上面源码中,最核心的部分就是start0();这个本地方法,也就是我们经常能在其他博文中看到的JNI方法,所谓JNI方法其实没有那么高大上,其实JNI就是Java平台用于和本地C代码进行互操作的API,JNI不支持Java类和 C++类之间的任何映射机制,这里只是简单的提一句。为什么说start0();是最核心的部分呢?看下图:

     那么我们重写的run方法是何时被调用的呢?可以看start方法的注释,如下图:

    Causes this thread to begin execution; the Java Virtual Machine
    calls the <code>run</code> method of this thread.
    

    这段注释是说:在开始执行这个线程时,JVM就会调用run方法,也就是说run方法就是被JNI方法start0调用的。

    通过源码总结要点:

    1.  Thread被构建后的NEW状态下,threadStatus这个内部属性值为0;

    2. 不能两次启动Thread,不然就会出现IllegalThreadStateException异常;

    3. group.threadStartFailed(this);可以看出线程启动后将会被加入到一个ThreadGroup中;

    4. 一个线程生命周期到了TERMINATED状态,是不允许调用start方法的。

    总结:jdk对start和run的设计,其实就是一个典型的模板模式,也就是父类编写算法结构代码,具体的逻辑实现由子类去完成。

      获取实时信息,关注公众号:『编程之艺术』,二维码:

  • 相关阅读:
    SQL Server经典函数之数字去零
    c# 定时执行python脚本
    SQL Server 存储过程生成流水号
    MySQL删除数据表中重复数据
    js封装正则验证
    .NET中将中文符号转换成英文符号
    WebApi中跨域解决办法
    JS生成GUID方法
    LINQ中的连接(join)用法示例
    LINQ分组取出第一条数据
  • 原文地址:https://www.cnblogs.com/winqi/p/11403013.html
Copyright © 2011-2022 走看看