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. Spring Boot(四) Mybatis-MySql

    Spring Boot(四) Mybatis-MySql 0.准备数据库表 -- ---------------------------- -- Table structure for person ...

  2. k阶斐波那契数列fibonacci第n项求值

    已知K阶斐波那契数列定义为:f0 = 0,  f1 = 0, … , fk-2 = 0, fk-1 = 1;fn = fn-1 + fn-2 + … + fn-k , n = k , k + 1, … ...

  3. Redis开发与运维:数据迁移

    问题 最近项目重构,提前想把一台上的redis实例转移到另一台redis实例上. 源redis数据库:阿里云Redis.VPC网络.Server版本2.8.19 目标数据库:阿里云Redis.VPC网 ...

  4. 我又不是你的谁--java instanceof操作符用法揭秘

    背景故事 <曾经最美>是朱铭捷演唱的一首歌曲,由陈佳明填词,叶良俊谱曲,是电视剧<水晶之恋>的主题曲.歌曲时长4分28秒. 歌曲歌词: 看不穿你的眼睛 藏有多少悲和喜 像冰雪细 ...

  5. 项目三:ssm仓库管理系统

    声明:项目来源于网络,尊重原创,学习使用,仅在此记录 项目介绍 ssm仓库管理系统,功能模块:客户信息管理,供应商管理,货物管理,仓库管理,仓库管理员管理,仓库出入口管理,仓库库存记录管理,系统日志管 ...

  6. Springboot2.x + ShardingSphere 实现分库分表

    之前一篇文章中我们讲了基于Mysql8的读写分离(文末有链接),这次来说说分库分表的实现过程. 概念解析 垂直分片 按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用. 在拆分之前 ...

  7. 为什么要学3D建模呢?你看中的肯定是这几点

    游戏行业的大环境 互联网的形态一直以来都是2D模式的,但是随着3D技术的不断进步,在未来的5年时间里,将会有越来越多的互联网应用以3D的方式呈现给用户,包括网络视讯.电子阅读.虚拟社区.网络游戏.电子 ...

  8. Js正则学习笔记

    众所周知正则表达式是十分强大的存在,编码时能够熟练使用正则能够极大的简化代码,因此掌握正则非常有必要. 创建正则语法: // 创建正则的两种方式// 1.构造函数 let reg = new RegE ...

  9. docker-compose 的使用

    1.安装docker-compose,参考官方教程:https://docs.docker.com/compose/install/ [chenjl@ipha-dev71- ~]$ sudo curl ...

  10. UI测试之元素定位

    定位方式优先级选择:  ID>Name>CSS>XPath 1.使用id定位 2.使用name定位 3.使用class定位 4.使用css选择器定位 示例xml: <?xml ...