Java里一个线程两次调用start()方法会出现什么情况
时间:2021-04-17
本文章向大家介绍Java里一个线程两次调用start()方法会出现什么情况,主要包括Java里一个线程两次调用start()方法会出现什么情况使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
这里有一道经典的面试题:“一个线程两次调用start()方法会出现什么情况?”,咱们这次结合案例从线程源码的角度炒剩饭。
答:Java的线程是不允许启动两次的,第二次调用时,线程可能处于终止或者其它(非NEW)状态,必然会抛出IllegalThreadStateException,这是一种运行时异常,多次调用start被认为是编程错误。如果业务需要线程run中的代码再次执行,请重新启动一个线程实例。
应聘的时候回答这么多就可以了,下面从源码角度深入分析为什么不行,如果面试官刨根问底,咱们也可以底气十足。
案例分析
package com.sc.register;
/**
* 在同一线程上两次调用start方法
*
* @author Wiener
* @date 2021/4/9
*/
public class ReStartThread implements Runnable {
@Override
public void run() {
System.out.println("In run() method.");
}
public static void main(String[] args) {
ReStartThread obj = new ReStartThread();
Thread thread1 = new Thread(obj, "Thread-ReStart");
thread1.start();
System.out.println("当前线程状态是:" + thread1.getState());
// will throw java.lang.IllegalThreadStateException at runtime
thread1.start();
}
}
执行结果如下:
当前线程状态是:RUNNABLE
in run() method, method completed.
Exception in thread "main" java.lang.IllegalThreadStateException
at java.base/java.lang.Thread.start(Thread.java:794)
at com.sc.register.ReStartThread.main(ReStartThread.java:22)
Process finished with exit code 1
线程源码分析
Thread类中,start()函数第一行代码就是校验线程状态,如果状态不是新建,则抛出运行时异常IllegalThreadStateException,而且备注里有声明:
/**
* Java thread status for tools, default indicates thread 'not yet started'
*/
private volatile int threadStatus;
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(); // ①
在①处打断点,以debug模式启动案例,可以看到第二个start()执行后,线程状态 threadStatus 不为0,故抛出异常。调试结果如下图所示:
温馨提示:threadStatus的值在不同机器的运行结果可能不一样。
原文地址:https://www.cnblogs.com/east7/p/14670750.html
- 报警系统QuickAlarm之频率统计及接口封装
- 如何使用Sentry管理Hive外部表权限
- 报警系统QuickAlarm之报警规则解析
- 报警系统QuickAlarm之报警规则的设定与加载
- 报警系统QuickAlarm之报警执行器的设计与实现
- 如何在Kerberos与非Kerberos的CDH集群BDR不可用时复制数据
- 一个可扩展的报警系统Quick-Alarm
- 如何借助GitHub搭建属于自己的maven仓库
- Java可以如何实现文件变动的监听
- 如何在CDH中安装Kudu&Spark2&Kafka
- 秒懂 javascript 拖拽上传文件
- 一款轻量级树形控件EasyTreeview
- 大白话谈 Git
- 打造一个属于自己的 server
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- ThinkPHP5 的简单搭建和使用详解
- php中怎么执行linux命令详解
- phpMyAdmin通过密码漏洞留后门文件
- php 调用百度sms来发送短信的实现示例
- MySQL 8.0 新特性:快速加列
- php判断电子邮件是否正确办法
- 用Laravel Sms实现laravel短信验证码的发送的实现
- kubernetes 近期进展 - 1.14-1.19
- Kubernetes 1.19.0——cronjob
- php获取微信openid方法总结
- Laravel 关联模型-关联新增和关联更新的方法
- 如何解决PHP获取不到SESSION信息之一般情况
- PHP实现通过二维数组键值获取一维键名操作示例
- laravel 判断查询数据库返回值的例子
- laravel框架数据库配置及操作数据库示例