五.线程的调度

分时调度模型

分时调度模型是指让所有的线程轮流获得CPU的使用权,并且平均分配每个线程占用的CPU的时间片。

抢占式调度模型

抢占式调度模型是指让可运行池中优先级高的线程优先占用CPU,而对于优先级相同的线程,随机选择一个线程使其占用CPU,当它失去了CPU的使用权后,再随机选择其他线程获取CPU使用权。

Java虚拟机默认采用抢占式调度模型,通常情况下程序员不需要去关心它,但在某些特定的需求下需要改变这种模式,由程序自己来控制CPU的调度。

 线程的优先级

  • 在应用程序中,如果要对线程进行调度,最直接的方式就是设置线程的优先级。优先级越高的线程获得CPU执行的机会越大,而优先级越低的线程获得CPU执行的机会越小。线程的优先级用1~10之间的整数来表示,数字越大优先级越高。
  • 除了可以直接使用数字表示线程的优先级,还可以使用Thread类中提供的三个静态常量表示线程的优先级,如下表。

 程序在运行期间,处于就绪状态的每个线程都有自己的优先级。例如:main线程具有普通优先级。然而线程优先级不是固定不变的,可以通过Thread类的setPriority(int newPriority)方法进行设置,setPriority()方法中的参数newPriority接收的是1~10之间的整数或者Thread类的三个静态常量。

线程的优先级案例

public class Demo06 {
    public static void main(String[] args) {
        //创建两个线程
        Thread minPriority=new Thread(new MinPriority(),"优先级较低的线程");
        Thread maxPriority=new Thread(new MinPriority(),"优先级较高的线程");
        minPriority.setPriority(Thread.MIN_PRIORITY);//设置线程的优先级为1
        maxPriority.setPriority(Thread.MAX_PRIORITY);//设置线程的优先级为10
        //开启两个线程
        maxPriority.start();
        minPriority.start();
    }
}
//定义MaxPriority实现Runnable接口
class MaxPriority implements Runnable{
    public void run(){
        for(int i=0;i<10;i++){//使用for循环打印正在发售的票数,
            System.out.println(Thread.currentThread().getName()+"正在输出"+i);
        }
    }
}
//定义MinPriority实现Runnable接口
class MinPriority implements Runnable{
    public void run(){
        for(int i=0;i<10;i++){//使用for循环打印正在发售的票数,
            System.out.println(Thread.currentThread().getName()+"正在输出"+i);
        }
    }
}

运行结果

 结果分析

从运行结果可以看出,优先级较高的maxPriority线程先运行了,运行完毕后优先级较低的minPriority线程才开始运行。所以优先级越高的线程获取CPU切换时间片的机率越大。

注意:虽然Java中提供了10个线程优先级,但是这些优先级需要操作系统的支持,不同的操作系统对优先级的支持是不一样的,不会和Java中线程优先级一一对应,因此,在设计多线程应用程序时,其功能的实现一定不能依赖于线程的优先级,而只能把线程优先级作为一种提高程序效率的手段。

线程休眠

已知优先级高的程序会先执行,而优先级低的程序会后执行。如果希望人为地控制线程,使正在执行的线程暂停,将CPU让给别的线程,这时可以使用静态方法sleep(long millis),该方法可以让当前正在执行的线程暂停一段时间,进入休眠等待状态。当前线程调用sleep(long millis)方法后,在指定时间(单位毫秒)内该线程是不会执行的,这样其他的线程就可以得到执行的机会了。

sleep(long millis)方法声明会抛出InterruptedException异常,因此在调用该方法时应该捕获异常,或者声明抛出该异常。

 案例演示:sleep(long millis)方法在程序中的使用

public class Demo07 {
    public static void main(String[] args) throws InterruptedException{
        //创建一个线程
        new Thread(new SleepThread()).start();
        for(int i=1;i<=10;i++){
            if(i==5){
                Thread.sleep(2000);//当前线程休眠2秒
            }
            System.out.println("主线程正在输出"+i);
            Thread.sleep(500);//当前线程休眠500毫秒
        }
    }
}
class SleepThread implements Runnable{
    public void run(){
        for(int i=0;i<=10;i++){
            if(i==3){
                try{
                    Thread.sleep(2000);//当前线程休眠2秒
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println("SleepThread线程正在输出"+i);
            try{
                Thread.sleep(500);//当前线程休眠500毫秒
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

运行结果

 结果分析

在主线程与SleepThread类线程中分别调用了Thread的sleep(500)方法让其线程休眠,目的是让一个线程在打印一次后休眠500毫秒,从而使另一个线程获得执行的机会,这样就可以实现两个线程的交替执行。

注意:sleep()是静态方法,只能控制当前正在运行的线程休眠,而不能控制其他线程休眠。当休眠时间结束后,线程就会返回到就绪状态,而不是立即开始运行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

享受当下.26

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值