zoukankan      html  css  js  c++  java
  • 线程八大基础核心二(启动线程)

     1.引子

    在java多线程并发编程中,有八大基础核心。考考你:看看都有哪八大基础核心呢?它们分别是:

      1.创建线程的方式

      2.线程启动

      3.线程停止

      4.线程生命周期

      5.线程相关的方法

      6.线程相关的属性

      7.线程异常处理

      8.线程安全

    今天我们从第二个基础核心开始:启动线程

    2.考考你

    #前情回顾:

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

    Thread t1 = new Thread();

    t1.start();

    #考考你:

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

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

    3.两次调用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方法启动线程");
        }
    }

    4.直接调用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());
        }
    }

    5.线程启动流程分析

    5.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 */
                }
            }
        }

    5.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();
            }
        }

    6.讨论分享

    #线程启动流程:

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

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

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

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

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

    #考考你答案:

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

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

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

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

     

  • 相关阅读:
    介绍 Jersey 依赖
    Jersey 2.x 分支 Java SE 兼容性
    Confluence 6 管理 Atlassian 提供的 App
    Confluence 6 针对站点维护使用只读模式
    Confluence 6 协同编辑问题解决
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
    Confluence 6 管理协同编辑
  • 原文地址:https://www.cnblogs.com/itall/p/12258418.html
Copyright © 2011-2022 走看看