zoukankan      html  css  js  c++  java
  • 关于多线程start()方法原理解读

    1、为什么启动线程不用run()方法而是使用start()方法

    run()方法只是一个类中的普通方法,调用run方法跟调用普通方法一样

    而start()是创建线程等一系列工作,然后自己调用run里面的任务内容。

    验证代码:

    /**
     * @data 2019/11/8 - 下午10:29
     * 描述:run()和start()
     */
    public class StartAndRunMethod {
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            };
            runnable.run();
    
            new Thread(runnable).start();
        }
    }

    结果:

    main
    Thread-0


    2、start()源码解读

    • 启动新线程检查线程状态
    •     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();

      关于threadStatus源码:

    •     /*
           * Java thread status for tools, default indicates thread 'not yet started'
           */
          private volatile int threadStatus;

      通过代码可以看到就是threadStatus就是记录Thread的状态,初始线程默认为0.

    • 加入线程组
    •  /* 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);
    • 调用start0()
    • 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 */
                  }
              }
          }

      start0()方法使用c++编写的方法,这些代码在gdk代码中,所以这里不再这里探究了。


    3、start()方法不能使用多次

    通过刚刚源码分析,就知道start方法刚开始就检查线程状态,当线程创建后或结束了,该状态就不同于初始化状态就会抛出

    IllegalThreadStateException异常。

    测试代码:

    /**
     * @data 2019/11/8 - 下午11:57
     * 描述:start不可以使用多次
     */
    public class CantStartTwice {
        public static void main(String[] args) {
            Thread thread = new Thread();
            thread.start();
            thread.start();
        }
    }
    start不可以使用多次

    
    

     4、注意点:

    start方法是被synchronized修饰的方法,可以保证线程安全。

    由jvm创建的main方法线程和system组线程,并不会通过start来启动。

  • 相关阅读:
    [ACM]HDU Problem 2000 + Java
    [测试开发面试]zyb面试题总结
    [ACM]HDU Problem 1001 + Java
    [ACM]HDU Problem 1002 + Java
    [ACM]HDU Problem 1000 + Java
    [Intellij Idea]激活与配置
    [Android开发]合集(随时更新)
    [Android开发]前端样式设计合集(随时更新)
    [Android开发]emulator无法启动的问题
    [Intellij Idea] IDE使用技巧帖集合(随时更新)
  • 原文地址:https://www.cnblogs.com/zitai/p/11823968.html
Copyright © 2011-2022 走看看