Java 线程的状态
线程状态
线程有以下 6 种状态:
- New(新创建)
- Runnable(可运行)
- Blocked(被阻塞)
- Waiting(等待)
- Time waiting(计时等待)
- Terminated(被终止)
确定一个线程的当前状态,可以调用 getState 方法。
新创建线程
使用 new 创建线程时,比如 new Thread(r),线程还没有运行,它的状态是 new。
可运行线程
调用 start 方法,线程处于 runnable 状态。一个可运行线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。
一旦一个线程开始运行,它并不始终保持运行,线程调度的细节依赖于操作系统。抢占式调度系统给每一个可运行线程一个时间片来执行任务,当时间片用完,操作系统剥夺该线程的运行权,给另一个线程运行机会,选择下一个线程时,操作系统会考虑线程的优先级。
所有的桌面以及服务器操作系统都采用抢占式调度。有些小型设备可能使用协作式调度,一个线程只有在调用 yield 方法、或者被阻塞或等待时,线程才失去控制权。
在具有多个处理器的机器上,每一个处理器运行一个线程,可以有多个线程并行运行。如果线程的数量多于处理器的数量,调度器依然采用时间片机制。总之,在任何时刻,一个可运行线程可能正在运行也可能没有运行。
被阻塞线程和等待线程
- 当一个线程试图获得一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态。当所有其他线程释放该锁,并且线程调度器允许本线程持有它时,该线程变为非阻塞状态。
- 当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。当调用 Object.wait 或者 Thread.join 方法,或者是等待 Lock 或 Condition 时,就会出现这种情况。
- 有几个方法有一个超时参数,调用它们导致线程进入计时等待状态(Thread.sleep、Object.wait、Thread.join 等)。
被终止的线程
线程因以下 2 个原因之一而被终止:
- run 方法正常退出而自然死亡。
- 因为一个没有捕获的异常终止了 run 方法而意外死亡。
线程属性
线程优先级
每一个线程都有一个优先级。默认情况下,一个线程继承它父线程的优先级。可以用 setPriority 方法提高或降低任何一个线程的优先级。优先级的取值范围是 MIN_PRIORITY(1)与 MAX_PRIORITY(10)之间的任何值。NORM_PRIORITY 被定义为 5 。当线程调度器选择新线程时,它首先选择具有较高优先级的线程。
如果有几个高优先级的线程没有进入非活动状态,低优先级的线程可能永远也不会执行。
守护线程
可以在线程启动之前使用 setDaemon(true) 将线程转换为守护线程。守护线程的唯一用途就是为其他线程提供服务,当只剩下守护线程时,虚拟机就退出了。
守护线程应该永远不会去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。