一个线程两次调用start()方法会出现什么情况?
Java的线程是不允许启动两次的,第二次调用时,线程可能处于终止或者其它(非NEW)状态,必然会抛出IllegalThreadStateException,
这是一种运行时异常,多次调用start被认为是编程错误。如果业务需要线程run中的代码再次执行,请重新启动一个线程实例。
一个线程本身是具备一个生命周期的。
在Java里面,线程的生命周期包括6种状态。
- NEW,线程被创建还没有调用start启动
- RUNNABLE,在这个状态下的线程有可能是正在运行,也可能是在就绪队列里面等待操作系统进行调度分配CPU资源。
- BLOCKED,线程处于锁等待状态
- WAITING,表示线程处于条件等待状态,当触发条件后唤醒,比如wait/notify。
- TIMED_WAIT,和WAITING状态相同,只是它多了一个超时条件触发
- TERMINATED,表示线程执行结束
当我们第一次调用start()方法的时候,线程的状态可能处于终止或者非NEW状态下的其他状态。
再调用一次start(),相当于让这个正在运行的线程重新运行,不管从线程的安全性角度,还是从线程本身的执行逻辑,都是不合理的。
因此为了避免这个问题,在线程运行的时候会先判断当前线程的运行状态。
线程到底是什么?
进程是程序的一次执行过程,是资源的基本单位; 进程包括线程,线程是调度和分派的基本单位。
从操作系统的角度,可以简单认为,线程是系统调度的最小单元,一个进程可以包含多个线程,作为任务的真正运作者,有自己的栈(Stack)、寄存器(Register)、本地存储(Thread Local)等,但是会和进程内其他线程共享文件描述符、虚拟地址空间等。
从线程生命周期的状态开始展开,那么在 Java 编程中,有哪些因素可能影响线程的状态呢?主要有:
线程自身的方法,除了 start,还有多个 join 方法,等待线程结束;yield 是告诉调度器,主 动让出 CPU;另外,就是一些已经被标记为过时的 resume、stop、suspend 之类,据我所知,在 JDK 最新版本中,destory/stop 方法将被直接移除。 基类 Object 提供了一些基础的 wait/notify/notifyAll 方法。如果我们持有某个对象的 Monitor 锁,调用 wait 会让当前线程处于等待状态,直到其他线程 notify 或者 notifyAll。 所以,本质上是提供了 Monitor 的获取和释放的能力,是基本的线程间通信方式。 并发类库中的工具,比如 CountDownLatch.await() 会让当前线程进入等待状态,直到 latch 被基数为 0,这可以看作是线程间通信的 Signal。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端