zoukankan      html  css  js  c++  java
  • 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的值在不同机器的运行结果可能不一样。


      读后有收获,小礼物走一走,请作者喝咖啡。

    赞赏支持

  • 相关阅读:
    从一个iOS毛头小子到现在的高级工程师, 我总结了一些经验,先跟大家分享一下一些好的资料
    iOS面试题---Objective_C语言特性:分类、扩展、代理、通知、KVO、KVC、属性
    200道iOS面试题面试题整理,底层、技术亮点公司需要的这里都有
    [iOS 开发] iOS 开发从菜鸟到高手?听听他们怎么说
    2020年面向iOS开发人员的知识点总结(更新中)
    OC项目转Swift指南
    来自老程序员的10条中肯建议
    面对职业瓶颈,iOS 开发人员应该如何突破?
    憨憨程序猿,不要让你的技术被简历埋没了
    总结:实现线程同步的八种方式
  • 原文地址:https://www.cnblogs.com/east7/p/14670750.html
Copyright © 2011-2022 走看看