线程调度

        线程的调度不是跨平台的,不仅取决于Java虚拟机,还依赖于操作系统。Java虚拟机采用抢占式调度,即优先让优先级高的线程先运行,如果优先级相同,则随机选择一个线程。Java线程的调度不是分时的,同时启动多个线程后,不能保证每个线程轮流得到相等的CPU时间片。
        如果希望明确地让一个线程给其他线程运行的机会,有以下方法:

  • 调整各个线程的优先级
  • 处于运行态的线程调用Thread.sleep()方法
  • 处于运行态的线程调用Thread.yield()方法
  • 处于运行态的线程调用另一个线程的join()方法
调整各个线程的优先级

优先级高的线程会获得优先运行的机会。Thread类的setPriority(int)和getPriority()方法分别用来设置优先级和获得优先级。优先级是整数,取值范围是1 ~ 10,Thread有3个静态常量:

  • MAX_PRIORITY:值为10,最高优先级
  • MIN_PROIRITY:值为1,最低优先级
  • NORM_PRIORITY:值为5,默认优先级
    每个线程都有默认优先级,如果线程A创建了线程B,那么它们具有相同的优先级。
线程睡眠:Thread.sleep()方法

当一个线程在运行态执行了sleep()方法,那么它会放弃cpu,转到阻塞态,结束睡眠时,转到就绪态。
如果线程在睡眠时被中断,就会收到一个InterrupedException异常,线程跳到异常处理代码块。



public class Main extends Thread{
    public void run() {
        try {
            sleep(1000);
            System.out.println("Sleep over");
        } catch (InterruptedException e) {
            System.out.println("Interruped!");
        }
        System.out.println("end");
    }
    public static void main(String args[]) throws Exception {
        Main m = new Main();
        m.start();
        //Thread.sleep(2000);
        m.interrupt();
        
    }
}
运行结果:
Interruped!
end

主线程启动Main线程,Main线程睡眠1秒,此时Main线程被中断,所以会转到异常处理代码块。



public class Main extends Thread{
    public void run() {
        try {
            sleep(1000);
            System.out.println("Sleep over");
        } catch (InterruptedException e) {
            System.out.println("Interruped!");
        }
        System.out.println("end");
    }
    public static void main(String args[]) throws Exception {
        Main m = new Main();
        m.start();
        Thread.sleep(2000);
        m.interrupt();
        
    }
}
运行结果:
Sleep over
end

主线程启动Main线程,Main线程睡眠1秒,此时主线程睡眠2秒后中断Main线程的睡眠,而2秒后Main线程已经是运行态,所以中断无效,不会触发异常处理。

线程让步:Thread.yield()方法

当线程执行了yield()静态方法时,如果此时有相同或更高优先级的线程处于就绪态,那么,当前处于运行态的线程会被放到可运行池中,转到就绪态,另外一个符合要求的线程运行。如果没有符合的线程,yield()方法什么也不做。

等待其他线程结束:join()方法

当运行态的线程调用另外一个线程的join()方法,当前线程将转为阻塞态,直到另外一个线程运行结束,它才会恢复运行(阻塞态->就绪态)。



public class Main extends Thread{
    public void run() {
        for(int i=0;i<5;i++) {
            System.out.println(getName()+" : "+i);
        }
    }
    public static void main(String args[]) throws Exception {
        Main m1 = new Main();
        m1.setName("m1");
        m1.start();
        System.out.println("main:join m1");
        m1.join();//主线程等待m1线程结束
        System.out.println("main:end");
        
    }
}
运行结果:
main:join m1
m1 : 0
m1 : 1
m1 : 2
m1 : 3
m1 : 4
main:end

join()有2种重载形式:

public void join()
public void join(long timeout)

timeout参数设定当前线程被阻塞的时间,单位:毫秒。如果把上面改为m1.join(1000),那么当主线程被阻塞的时间超过了1秒时,或者m1线程运行结束时,主线程恢复运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃鱼的ねこ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值