Java线程调度器
每个虚拟机都有一个线程调度器,确实在任何时刻运行哪个线程。有两种线程调度器:1、抢占式(preemptive)2、协作式(cooperative) 抢占式线程高度器确实线程何时已经公平地享用了CPU时间,然后暂停此线程上,将CPU控制权交给另外的线程。协作式线程调度器会在将CPU控制权交给其他线程前,等待运行中的线程自己斩停。与使用抢占式线程式调度的虚拟机相比,使用协作式线程调度器...
每个虚拟机都有一个线程调度器,确实在任何时刻运行哪个线程。有两种线程调度器:
1、抢占式(preemptive)
2、协作式(cooperative)
抢占式线程高度器确实线程何时已经公平地享用了CPU时间,然后暂停此线程上,将CPU控制权交给另外的线程。协作式线程调度器会在将CPU控制权交给其他线程前,等待运行中的线程自己斩停。与使用抢占式线程式调度的虚拟机相比,使用协作式线程调度器的虚拟机更容易使线程陷入“饥饿”,因为一个高优先级的非协作线程会独占整个CPU。
所有JAVA虚拟机都保证了在不同优先级之间使用抢占式线程调度。即,当高优先级线程准备运行时,而低优先级线程正在运行,虚拟机会或早或晚(可能是早)暂停低优先级线程,让高优先级的线程运行。高优先级线程就抢占(preempt)了低优先级别线程。
JAVA的线程的优先级,以1到10的整数指定。当多个线程可以运行时,VM一般会运行最高优先级的线程,但这并非严格的规则。在JAVA中,10是最高优先级,1是最低优先级。默认优先级是5,除非有意设置,否则创建的线程都默认是这个优先级。
JAVA以三个命名常量来指定三个优先级(1、5、10):
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
线程的优先级可以使用setPriority()方法来改变:
pubilc final void setPriority(int newPriority);
使用getPriority()方法可以返回线程的当前优先级:
public final int getPriority();
如果多个相同优先级的线程准备运行,这种情况有些棘手。抢占式线程调度偶尔会暂停其中一个线程,让下一个线程得到一些CPU时间。但是,协作式线程高度器不会这样。它等待正在运行的线程显式放弃控制并到达停止点(即停止)。如果运行中线程永远不会放弃控制权,也永远不会到达停止点,并且没有更高优先级线程抢占运行中线程,那么其它所有线程都会“饥饿”。这是件坏事情。重要的一点是,要确保所有线程自身定期地暂停,这样其他线程才可以有运行的机会。
注意:
如果在使用抢占式线程调度的VM上开发,饥饿问题就很难发现。这是因为没有过在你的机器上出现问题,并不表示不会在客户机器上出现,如果他们的VM使用协作式线程调度的话,就很可能出现问题。目前大多数虚拟机都使用抢占式线程调度,但有些更早的虚拟机是协作调度的。
为了有利其他线程,一个线程有10种方式可以暂停或指示准备暂停。如下:
1、可以在I/O时阻塞
2、可以在同步对象时阻塞
3、可以放弃
4、可以休眠
5、可以连接另一个线程
6、可以等待一个对象
7、可以结束
8、可以被更高优先级线程抢占
9、可以被挂起
10、可以停止
你应当检测你编写的的每个run()方法,确保这这些条件之一以合理的频率出现。最后两种可能性已经废弃不用,因为它们可能会让对象处于不一致的状态。
更多推荐
所有评论(0)