本篇属于【Java多线程系列】文章第二章【多线程编程的实现与应用】的第三小节内容,我们会来学习线程的优先级概念。
线程的调度
在学习的优先级概念前,我们先要了解Java的线程调度系统。在Java中主要有两种主要的调度方式 :
(1)协同式线程调度(Cooperative )
(2)抢占式线程调度(PreemptiveThreads-Scheduling)
协同式线程调度
使用协同式调度的多线程系统,线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另外一个线程上。
协同式多线程的最大好处是实现简单,而且由于线程要把自己的事情干完后才会进行线程切换,切换操作对线程自己是可知的,所以没有什么线程同步的问题。Lua语言中的“协同例程”就是这类实现。
它的坏处也很明显:线程执行时间不可控制,甚至如果一个线程编写的问题,一直不告知系统进行线程切换,那么程序就会一直阻塞在那里。很久以前的Windows3.x系统就是使用协同式来实现多线程多任务的,相当不稳定,一个进程坚持不让出CPU执行时间就可能会导致整个系统崩溃。
抢占式线程调度
抢占式调度的多线程系统,那么每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定(在Java中,Thread.yield()可以让出执行时间,但是要获取执行时间的话,线程本身是没有什么办法的)。
在这种实现线程调度的方式下,线程的执行时间是系统可控的,也不会有一个线程导致整个进程阻塞的问题,Java使用的线程调度方式就是抢占式调度。与前面所说的Windows3.x的例子相对,在Windows9x/NT内核中就是使用抢占式来实现多进程的,当一个进程除了问题,我们还可以使用任务管理器把这个进程杀掉,而不至于导致系统崩溃。
虽然Java线程调度是系统自动完成的,但是我们还是可以“建议”系统给默写线程多分配一点执行时间,另外的一些线程则可以少分配一点,这项操作可以通过设置线程优先级来完成。Java语言一共设置了10个级别的线程优先级(Thread.MIN_PRIORITY至Thread.MAX_PRIORITY),这两个线程同时处于Ready状态时,优先级越高的线程越容易被系统选择执行。
线程的优先级
线程的优先级代表该线程的重要程度。如果有大量线程都被堵塞,都在等候运行,会尽可能地运行优先级比较的线程。
但这并不表示优先级较低的线程不会运行。若程序的优先级较低,只不过表示它被允许执行的机会小一些而已。
Thread.currentThread().getPriority() //获得当前线程的优先级
public final void setPriority(int newPriority) //设置线程的优先级
线程的优先级设置可以为1-10的任一数值, Thread类中定义了三个线程优先级, 分别是:MIN_PRIORITY(1)、NORM_PRIORITY(5)、MAX_PRIORITY(10), 一般情况下推荐使用这几个常量, 不要自行设置数值。
不同平台, 对线程的优先级的支持不同,编程的时候不要过度依赖线程优先级。程序的运行顺序不能完全依赖于设置的优先级顺序。
本文系【程序因子】版权作品,未经授权严禁转载,同时也欢关注同名公众号【程序因子】迎投稿及合作。