线程基础核心 02 启动线程

admin / 开发 / ... / Reads: 843

1.线程的启动

1.在java编程语言中,创建好线程对象后,通过调用start方法,启动线程

Thread t1 = new Thread();
t1.start();

考考你:

1.问题一:可以调用两次start方法吗?

2.问题二:可以调用run方法,启动线程吗?

2.两次调用start方法

package com.anan.thread.startthread;

/**
 * 两次调用start方法,启动线程
 */
public class TwoStartMethodDemo {

    public static void main(String[] args) {

        // 创建Runnable和Thread对象
        Runnable r1 = new MyRunnable();
        Thread t1 = new Thread(r1);

        // 调用两次start方法
        t1.start();
        t1.start();

    }
}

/**
 * 实现Runnable方式,创建线程
 */
class MyRunnable implements Runnable{

    public void run() {
        System.out.println("两次调用start方法启动线程");
    }
}

19

3. 直接调用run方法

package com.anan.thread.startthread;

/**
 * 直接调用run方法启动线程
 */
public class RunMethodDemo {

    public static void main(String[] args) {
        // 创建Runnable和Thread对象
        Runnable r1 = new MyRunnable2();
        Thread t1 = new Thread(r1);

        // 调用run方法
        t1.run();

    }
}

/**
 * 实现Runnable方式,创建线程
 */
class MyRunnable2 implements Runnable{

    public void run() {
        System.out.println("调用run方法启动线程,当前线程:"+Thread.currentThread().getName());
    }
}

1

4.线程启动流程分析

4.1.方法源码分析: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()
     *
     *注释:启动线程start方法源码,启动线程的流程是:
     *    第一:判断当前线程状态
     *    第二:将当前线程加入线程组
     *    第三:调用本地方法start0(),启动新线程
     */
    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".
         */
        // 第一:判断当前线程状态,如果不是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(),启动新线程
            // 彩蛋:java编程语言的线程实现,是基于操作系统【内核】线程的方式实现
            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 */
            }
        }
    }

4.2.方法源码分析:run

/**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     *
     *注释:运行线程run方法源码,在方法内部:
     *    第一:调用了target对象的run方法
     *    第二:target对象是Runnable对象,相当于普通对象调用方法
     *    第三:因此不会开启新的线程,还是在主线程main中执行
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

5.讨论分享

线程启动流程:

1.在java编程语言中,正确的启动线程方式,是调用start方法

2.在start方法内部启动流程是:

  2.1.判断当前线程状态,是否是NEW状态

  2.2.如果当前线程是NEW状态,将当前线程加入线程组

  2.3.调用本地方法start0(),开启线程

#考考你答案:

1.可以调用两次start方法吗?

答案:不能,因为线程只有在NEW状态下,可以启动

2.可以调用run方法,启动线程吗?

答案:不能,因为直接调用run方法,相当于在主线程main下调用普通方法,并没有开启新的线程

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。

Comments

Make a comment

Author: admin

Publish at: ...

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,熟悉 Java/Python/Go 等,喜欢读书,音乐和宅在家里。
专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。
Email: xujieiata@163.com

www.ultrapower.com ,王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。