一、线程调度之优先级
1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。
Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY
线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY
线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY
分配给线程的默认优先级,取值为5。
Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。
每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。
注意:
数字越大的优先级越高。但是,优先级高只是意味着该线程获取的 CPU 时间片相对多一些。并不是说是先让你走完。
下面来看一个简单的例子:
package day002;
/** * * 项目名称:JavaThread * 类名称:TestPriority * 类描述: * 创建人:liuc * 创建时间:2018年3月16日 下午4:04:08 * 修改人:liuc * 修改时间:2018年3月16日 下午4:04:08 * 修改备注: * @version * */
public class TestPriority extends Thread{
private String str;
/** * @Title: TestThread * @Description: TODO(这里用一句话描述这个方法的作用) * @param: @param string * @throws */
public TestPriority(String str) {
this.str = str;
}
/** * (non-Javadoc) * @see java.lang.Thread#run() */
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(str+"线程:"+i);
}
}
public static void main(String[] args) {
TestPriority t1 = new TestPriority("A");
TestPriority t2 = new TestPriority("B");
//设置线程优先级
//数字越大的优先级越高。但是,优先级高只是意味着该线程获取的 CPU 时间片相对多一些。
//并不是说是先让你走完。
//可以用Thread的常量MAX_PRIORITY(10)、NORM_PRIORITY(5)、
//MIN_PRIORITY(1)来设置优先级;
//或者用t1.setPriority(6)这种方式设置优先级
t1.setPriority(MAX_PRIORITY);
t2.setPriority(MIN_PRIORITY);
// t1.setPriority(6);
// t2.setPriority(2);
t1.start();
t2.start();
}
}
运行结果:
A线程:0
A线程:1
A线程:2
A线程:3
A线程:4
A线程:5
A线程:6
B线程:0
A线程:7
B线程:1
A线程:8
B线程:2
A线程:9
A线程:10
A线程:11
A线程:12
A线程:13
A线程:14
A线程:15
A线程:16
A线程:17
A线程:18
A线程:19
B线程:3
B线程:4
B线程:5
B线程:6
B线程:7
B线程:8
B线程:9
B线程:10
B线程:11
B线程:12
B线程:13
B线程:14
B线程:15
B线程:16
B线程:17
B线程:18
B线程:19
结果说明:
(01) 主线程main的优先级是5。
(02) t1的优先级被设为10,而t2的优先级被设为1。cpu在执行t1和t2的时候,根据时间片轮循调度,所以能够并发执行。
注意:
当线程的优先级设置超出了线程优先级的范围,如下面的例子:
package day002;
/** * * 项目名称:JavaThread * 类名称:TestPriority * 类描述: * 创建人:liuc * 创建时间:2018年3月16日 下午4:04:08 * 修改人:liuc * 修改时间:2018年3月16日 下午4:04:08 * 修改备注: * @version * */
public class TestPriority extends Thread{
private String str;
/** * @Title: TestThread * @Description: TODO(这里用一句话描述这个方法的作用) * @param: @param string * @throws */
public TestPriority(String str) {
this.str = str;
}
/** * (non-Javadoc) * @see java.lang.Thread#run() */
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(str+"线程:"+i);
}
}
public static void main(String[] args) {
TestPriority t1 = new TestPriority("A");
TestPriority t2 = new TestPriority("B");
//设置线程优先级
//数字越大的优先级越高。但是,优先级高只是意味着该线程获取的 CPU 时间片相对多一些。
//并不是说是先让你走完。
//可以用Thread的常量MAX_PRIORITY(10)、NORM_PRIORITY(5)、
//MIN_PRIORITY(1)来设置优先级;
//或者用t1.setPriority(6)这种方式设置优先级
t1.setPriority(11);
t2.setPriority(MIN_PRIORITY);
// t1.setPriority(6);
// t2.setPriority(2);
t1.start();
t2.start();
}
}
会报下面的错误:
Exception in thread "main" java.lang.IllegalArgumentException
at java.lang.Thread.setPriority(Thread.java:1089)
at day002.TestPriority.main(TestPriority.java:63)