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. Linux虚拟机中配置JDK环境变量(Ubuntu系统)

    首先通过Xshell中文件传输想你的虚拟机上传你的jdk,如图所示:(需要本机安装Xftp:链接: https://pan.baidu.com/s/1sWHmywZ2C6V2n4aa1FqqFg 提取 ...

  2. IT爱心求助站

    最近发生的一些事情,让我对自己的专业有了另外一层认识. 小尹同学,你是做软件的是吗?能否帮我看一下我的电脑问题? 老同学,我的电脑安装一个软件这么都装不上,能否帮我看一下呢? 邻居你好,我的手机怎么没 ...

  3. icon font在sketch中的下载与安装

    icon font的下载安装: 1.首先打开sketch--插件--管理插件--获取插件--搜索 icon font--点击icon font--clone or download--下载的是一个sk ...

  4. Python分布式爬虫必学框架Scrapy打造搜索引擎 ✌✌

    Python分布式爬虫必学框架Scrapy打造搜索引擎  ✌✌ (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 第1章 课程介绍 介绍课程目标.通过课程能学习到 ...

  5. PHP yield代替range生成范围内的数

    <?php function yieldRange($start, $limit, $step) { if ($start == $limit || $step == 0) { return $ ...

  6. caffe中softmax源码阅读

    (1) softmax函数                                      (1) 其中,zj 是softmax层的bottom输入, f(zj)是softmax层的top输 ...

  7. php在哪里写代码?

    php在哪里写代码? php可以在PhpStorm中写代码. PhpStorm 是 JetBrains 公司开发的一款商业的 PHP 集成开发工具,旨在提高用户效率,可深刻理解用户的编码,提供智能代码 ...

  8. 小程序预览pdf文件

    有个业务需求,需要在小程序查看客户已开的发票 发票地址: https://www.chinaeinv.com/p.jspa?cxxxxxxxxxxxx 刚开始是想利用webview当作外链进行跳转访问 ...

  9. 【网络安全】SQL注入、XML注入、JSON注入和CRLF注入科普文

    目录 SQL注入 一些寻找SQL漏洞的方法 防御SQL注入 SQL注入相关的优秀博客 XML注入 什么是XML注入 预防XML注入 JSON注入 什么是JSON注入 JSON注入的防御 CRLF注入 ...

  10. Intellij idea 一个窗口打开多模块并添加依赖

    打开多模块 ctrl+alt+shift+s 或者file->project sturcture 选择modules 添加 选择要添加的模块 选择从现有模块添加,不要选择从现在代码创建模块 添加 ...