线程的优先级
在应用程序中,如果要对线程进行调度,最直接的方式就是设置线程的优先级。优先级越高的线程获得CPU执行的机会越大,而优先级越低的线程获得CPU执行的机会越小。线程的优先级用1~10之间的整数来表示,数字越大优先级越高。除了可以直接使用数字表示线程的优先级,还可以使用Thread类中提供的三个静态常量表示线程的优先级,如表所示。
Thread静态常量 | 功能描述 |
---|---|
static int MAX_PRIORITY | 表示线程的最高优先级,相当于值10 |
static int MIN_PRIORITY | 表示线程的最低优先级,相当于值1 |
static int NORM_PRIORIY | 表示线程的普通优先级,相当于值5 |
程序在运行期间,处于就绪状态的每个线程都有自己的优先级,例如main线程具有普通优先级。然而线程优先级不是固定不变的,可以通过 Thread类的setPriority(int newPriority)方法对其进行设置,该方法中的参数newPriority接收的是1~10之间的整数或者Thread类的三个静态常量。接下来通过一个案例来演示不同优先级的两个线程在程序中的运行情况,如例所示。
package 多线程;
// 定义类MaxPriority实现Runnable接口
class MaxPriority implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "正在输出:" + i);
}
}
}
// 定义类MinPriority实现Runnable接口
class MinPriority implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "正在输出:" + i);
}
}
}
class Example07 {
public static void main(String[] args) {
// 创建两个线程
Thread minPriority = new Thread(new MinPriority(), "优先级较低的线程");
Thread maxPriority = new Thread(new MaxPriority(), "优先级较高的线程");
minPriority.setPriority(Thread.MIN_PRIORITY); // 设置线程的优先级为1
maxPriority.setPriority(10); // 设置线程的优先级为10
// 开启两个线程
maxPriority.start();
minPriority.start();
}
}
需要注意的是,虽然Java中提供了10个线程优先级,但是这些优先级需要操作系统的支持,不同的操作系统对优先级的支持是不一样的,不能很好的和Java中线程优先级一一对应,因此,在设计多线程应用程序时,其功能的实现一定不能依赖于线程的优先级,而只能把线程优先级作为一种提高程序效率的手段。
线程让步
线程让步可以通过yield()方法来实现,该方法和sleep()方法有点相似,都可以让当前正在运行的线程暂停,区别在于yield()方法不会阻塞该线程,它只是将线程转换成就绪状态,让系统的调度器重新调度一次。(下一次的调度如果是相同优先级的线程,随机调度)当某个线程调用yield()方法之后,只有与当前线程优先级相同或者更高的线程才能获得执行的机会。接下来通过一个案例来演示一下yield()方法的使用。
// 定义YieldThread类继承Thread类
class YieldThread extends Thread {
// 定义一个有参的构造方法
public YieldThread(String name) {
super(name); // 调用父类的构造方法
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
if (i == 3) {
System.out.print("线程让步:");
Thread.yield(); // 线程运行到此,作出让步
}
}
}
}
public class Example09 {
public static void main(String[] args) {
// 创建两个线程
Thread t1 = new YieldThread("线程A");
Thread t2 = new YieldThread("线程B");
// 开启两个线程
t1.start();
t2.start();
}
}
线程插队
现实生活中经常能碰到“插队”的情况,同样,在 Thread类中也提供了一个 join()方法来实现这个“功能”。当在某个线程中调用其他线程的join()方法时,调用的线程将被阻塞,直到被join()方法加人的线程执行完成后它才会继续运行。
public class Example10{
public static void main(String[] args) throws Exception {
// 创建线程
Thread t = new Thread(new EmergencyThread(),"线程一");
t.start(); // 开启线程
for (int i = 1; i < 6; i++) {
System.out.println(Thread.currentThread().getName()+"输入:"+i);
if (i == 2) {
t.join(); // 调用join()方法
}
Thread.sleep(500); // 线程休眠500毫秒
}
}
}
class EmergencyThread implements Runnable {
public void run() {
for (int i = 1; i < 6; i++) {
System.out.println(Thread.currentThread().getName()+"输入:"+i);
try {
Thread.sleep(500); // 线程休眠500毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}