Java线程调度

线程调度是指系统为线程分配处理器使用权的过程。

一、线程调度方式

Java线程调度的方式主要有两种:协同式线程调度(Cooperative Threads-Scheduling)抢占式线程调度(Preemptive Threads-Scheduling)

1)协同式线程调度

使用协同式线程调度的多线程系统,线程的执行时间由线程本身控制,线程把自己的工作执行完后,要主动通知系统切换到另一个线程。

优点:

实现简单,没有线程同步问题

缺点:

线程执行时间不可控,可能出现长时间阻塞

2)抢占式线程调度

使用抢占式调度的多线程系统,每个线程将由系统来分配时间,线程的切换不由线程本身决定。

优点:

不会出现长时间阻塞的问题。

3)线程优先级

Java语言设置了10个级别的线程优先级,在两个线程同时处于Ready状态时,优先级高的线程更容易被系统选择执行。

由于Java线程是通过映射到操作系统原生线程上实现的,所以线程调度最终取决于操作系统。操作系统不见得能和Java线程优先级一一对应,如Windows中只有7种优先级

另外在Windows中还存在“优先级推进器”(Priority Bossting),它的大致作用是当系统发现一个线程执行的“特别勤奋”时,可能会跨过优先级去为它分配执行时间。

因此,我们不能通过优先级来完全判断一组状态都为Ready的线程将会先执行哪一个。

二、线程状态

Java语言定义了5种线程状态,在任一时间点,一个线程只能有一种状态。

  1. 新建(New):创建后尚未启动该线程的状态
  2. 运行(Runable):包括了操作心痛线程状态中的Running和Ready,此状态的线程有可能在运行,也有可能在等待CPU分配执行时间
  3. 无限等待(Waiting):这种状态下的线程CPU不会为其分配时间,需要等待被其它线程唤醒,如:
    • 没有设置Timeout参数的Object.wait()方法
    • 没有设置Timeout参数的Thread.join()方法
    • LockSupport.park()方法
  4. 限期等待(Timed Waiting): 这种状态下的线程CPU不会为其分配时间,但无需等待被唤醒,在一定时间后有系统唤醒,如:
    • Thread.sleep()方法
    • 设置了Timeout参数的Object.wait()方法
    • 设置了Timeout参数的Thread.join()方法
    • LockSupport.parkNanos()方法
    • LockSupport.parkUntil()方法
  5. 阻塞(Blocked):线程被阻塞,等待获得排他锁,在另个一个线程放弃这个锁时发生
  6. 结束(Terminated):终止线程的线程状态,线程已执行结束

关于就绪队列、阻塞队列、挂起、激活等线程状态相关知识,请读者自行学习“操作系统”相关课程,不在这里赘述。