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来启动。

关于多线程start()方法原理解读的更多相关文章

  1. Java线程池原理解读

    引言 引用自<阿里巴巴JAVA开发手册> [强制]线程资源必须通过线程池提供,不允许在应用中自行显式创建线程. 说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销 ...

  2. Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net

    Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net 1. 提升单例有能力的1 2. 减少工作数量2 2.1. 减少距 ...

  3. 详细分析 Java 中实现多线程的方法有几种?(从本质上出发)

    详细分析 Java 中实现多线程的方法有几种?(从本质上出发) 正确的说法(从本质上出发) 实现多线程的官方正确方法: 2 种. Oracle 官网的文档说明 方法小结 方法一: 实现 Runnabl ...

  4. Java并发之AQS原理解读(三)

    上一篇:Java并发之AQS原理解读(二) 前言 本文从源码角度分析AQS共享锁工作原理,并介绍下使用共享锁的子类如何工作的. 共享锁工作原理 共享锁与独占锁的不同之处在于,获取锁和释放锁成功后,都会 ...

  5. Java并发之AQS原理解读(二)

    上一篇: Java并发之AQS原理解读(一) 前言 本文从源码角度分析AQS独占锁工作原理,并介绍ReentranLock如何应用. 独占锁工作原理 独占锁即每次只有一个线程可以获得同一个锁资源. 获 ...

  6. Java并发之AQS原理解读(一)

    前言 本文简要介绍AQS以及其中两个重要概念:state和Node. AQS 抽象队列同步器AQS是java.util.concurrent.locks包下比较核心的类之一,包括AbstractQue ...

  7. 从零开始实现lmax-Disruptor队列(四)多线程生产者MultiProducerSequencer原理解析

    MyDisruptor V4版本介绍 在v3版本的MyDisruptor实现多线程消费者后.按照计划,v4版本的MyDisruptor需要支持线程安全的多线程生产者功能. 由于该文属于系列博客的一部分 ...

  8. C# 多线程限制方法调用(monitor)

    多线程执行方法 改方法没有执行完时 别的方法不能调用次方法.用循环执行一个方法可以需要一分钟 在这一分钟只内任何 成员都不能再调用该方法. class MonitorSample { ; //生产者和 ...

  9. Java并发编程(一) 两种实现多线程的方法(Thread,Runnable)

    Java中实现多线程的方法有两种: 继承Thread类和实现Runnable方法,并重写Run方法,然后调用start()方法启动线程.使用Runnable会比Thread要好很多,主要是以下三个原因 ...

随机推荐

  1. Scala 学习笔记之集合(1)

    package com.citi.scala object CollectionDemo { def main(args: Array[String]): Unit = { /** * List */ ...

  2. Spark 学习笔记之 Spark history Server 搭建

    在hdfs上建立文件夹/directory hadoop fs -mkdir /directory 进入conf目录  spark-env.sh 增加以下配置 export SPARK_HISTORY ...

  3. Scala 学习笔记之集合(9) 集合常用操作汇总

    object CollectionDemo10 { def main(args: Array[String]): Unit = { var ls = List[Int](1, 2, 3) //向后增加 ...

  4. FFmpeg(七)音频的播放

    一.Open SL ES播放声音流程 简单说明 Open SL ES是android内部的接口,本身可以解码音频,但是我们用FFmpeg,,也可以来录音 . SL引擎:上下文 混音器:两路声音的混合 ...

  5. git一步步上传自己的项目至github,及仓库更新

    一.使用git上传项目到github 首先登陆github账号,选择新建一个库,填写项目名称,描述 创建完成之后,跳转到下面的页面,下面红框中的网址要记住,在后面上传代码的时候需要使用 接下来,我们需 ...

  6. 02-18 scikit-learn库之k近邻算法

    目录 scikit-learn库之k近邻算法 一.KNeighborsClassifier 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 方法 1.4.1 kneighbors([X, n ...

  7. 常见Failed to load ApplicationContext异常解决方案!!

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  8. CentOS 7.7版本中NAT上网问题

    一.NAT(地址转换模式)概念 如果你的网络ip资源紧缺,但是你又希望你的虚拟机能够联网,这时候NAT模式是最好的选择.NAT模式借助虚拟NAT设备和虚拟DHCP服务器,使得虚拟机可以联网. 二.具体 ...

  9. Windows系统调用中API的3环部分(依据分析重写ReadProcessMemory函数)

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API的3环部分 一.R3环API分析的重 ...

  10. django2-创建项目

    方式一:cmd或linux命令行下创建django项目(不常用,此处不做详细介绍) django-admin.py startproject autotest 方式二:使用pycharm专业版创建dj ...