大飞老师带你再看Java线程(四)

本篇来聊下线程让步-yield:
yield顾名思义是忍让,退让的意思, 在线程执行时,调用yield方法,可以让当前线程让出CPU资源.线程也从运行状态切换成就绪状态.这方法存在目的,一定程度上可以认为让同优先级的线程能得到适当的轮动.
注意:
1>当前线程yield让出CPU,不是进入阻塞状态,而是就绪状态,换句话说,线程还会马上参与CPU的争取.
2>线程并发情况下,线程让出CPU后,优先级高的线程有更高概率获取到CPU资源,但不绝对.
以下是验证过程:
环境: win7-4核CPU-8G内存

System.out.println(Runtime.getRuntime().availableProcessors()); //4

代码思路:开启5个线程,比CPU核数多一个, 执行相同逻辑, 从1打印到1000.线程t1,比其余的线程多一行代码: Thread.yield(), 礼让CPU.然后计算每个线程打印完成之后总时间.

public class App {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                long begin = System.currentTimeMillis();
                for (long i = 0;i < 1000; i++){
                    System.out.println(Thread.currentThread().getName() + "_" + i);
                    Thread.yield();
                }
                long end = System.currentTimeMillis();
                System.out.println("t1总用时:" + (end - begin));
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                long begin = System.currentTimeMillis();
                for (long i = 0;i < 1000; i++){
                    System.out.println(Thread.currentThread().getName() + "_" + i);
                }
                long end = System.currentTimeMillis();
                System.out.println("t2总用时:" + (end - begin));

            }
        }, "t2");
        Thread t3 = new Thread(new Runnable() {
            public void run() {
                long begin = System.currentTimeMillis();
                for (long i = 0;i < 1000; i++){
                    System.out.println(Thread.currentThread().getName() + "_" + i);
                }
                long end = System.currentTimeMillis();
                System.out.println("t3总用时:" + (end - begin));
            }
        }, "t3");

        Thread t4 = new Thread(new Runnable() {
            public void run() {
                long begin = System.currentTimeMillis();
                for (long i = 0;i < 1000; i++){
                    System.out.println(Thread.currentThread().getName() + "_" + i);
                }
                long end = System.currentTimeMillis();
                System.out.println("t4总用时:" + (end - begin));
            }
        }, "t4");
        Thread t5 = new Thread(new Runnable() {
            public void run() {
                long begin = System.currentTimeMillis();
                for (long i = 0;i < 1000; i++){
                    System.out.println(Thread.currentThread().getName() + "_" + i);
                }
                long end = System.currentTimeMillis();
                System.out.println("t5总用时:" + (end - begin));
            }
        }, "t5");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

在同一个默认优先级为5的情况下, 纯手工点击了100次, 最后计算完成次数:
同优先级最后结束次数

线程t1: 50次
线程t2:10次
线程t3:11次
线程t4:19次
线程t5:10次
修改代码, 在线程启动前,设置给5个线程设置优先级,

        //设置优先级
        t1.setPriority(5);
        t2.setPriority(10);
        t3.setPriority(5);
        t4.setPriority(5);
        t5.setPriority(1);

线程t1: 5 线程t2:10 线程t3/t4:5 线程t5:1, 再一次纯手工点击100次
不同优先级最后结束次数
线程t1: 61次
线程t2:1次
线程t3:9次
线程t4:10次
线程t5:19次

结论

上面实验,不过是相同优先级还是不同优先级,执行yield让步操作的线程大概率最后结束,也验证上述观点:
1> yield让出CPU, 同时也参与CPU争夺.
在相同优先级下, 线程t2, t3, t4, t5, 最后结束次数相差不大, 而在不同优先级下, 线程t3, t4 优先级相同都为5, 最后结束次数相差不大, 但是t2优先级为10, 只有1次最后结束, t5优先级最低为1, 最后结束次数仅次于t1. 这些数据验证了:

2> 高优先级的线程确实高概率争夺CPU.


猜你喜欢

转载自blog.csdn.net/wolfcode_cn/article/details/80900900