Java多线程六:线程优先级和yield()让步函数

线程优先级

线程的优先级将该线程的重要性传递给线程调度器,调度器将倾向于让优先权最高的线程先执行.然后这并不意味值优先权较低的线程将得不到执行.优先级较低的线程仅仅是执行的频率较低

package com.yin.myproject.demo.concurrent.base;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimplePriorities implements Runnable {
    private int countDown = 5;
    private volatile double d;
    private int priority;

    public SimplePriorities(int priority) {
        this.priority = priority;
    }

    public String toString() {
        return "name:" + Thread.currentThread().getName() + " priority: " + Thread.currentThread().getPriority()
                + ":prority:" + ": " + countDown;
    }

    public void run() {
        Thread.currentThread().setPriority(priority);
        while (true) {
            for (int i = 1; i < 10000; i++) {
                d += (Math.PI + Math.E) / (double) i;
                if (i % 1000 == 0) {
                    Thread.yield();
                }
            }
            System.out.println(this);
            if (--countDown == 0)
                return;
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
            exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
        }
        exec.shutdown();
    }
}

输出结果(每次执行结果都会有所偏差):

name:pool-1-thread-6 priority: 10: 5
name:pool-1-thread-3 priority: 1: 5
name:pool-1-thread-4 priority: 1: 5
name:pool-1-thread-1 priority: 1: 5
name:pool-1-thread-5 priority: 1: 5
name:pool-1-thread-2 priority: 1: 5
name:pool-1-thread-1 priority: 1: 4
name:pool-1-thread-6 priority: 10: 4
name:pool-1-thread-4 priority: 1: 4
name:pool-1-thread-3 priority: 1: 4
......

从执行结果上我们可以总结为一下两点:
1. 线程优先级并不能保证线程的执行顺序,优先级高的并不一定先执行,优先级低的也不一定不执行
2. 不要试图使用优先级来控制线程的执行顺序

yield()函数

首先看一下官方文档的解释:

A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.

大体意思是说,当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示。通俗的解释就是当前线程愿意让出CPU的使用权,可以让其他线程继续执行,但是线程调度器可能会停止当前线程继续执行,也可能会让该线程继续执行。
下面通过一个例子来演示Thread.yield()函数的使用:

public class YieldDemo01 {
    public static void main(String[] args) {
        YieldThread t1 = new YieldThread("线程一");
        YieldThread t2 = new YieldThread("线程二");
        t1.start();
        t2.start();
    }
}

class YieldThread extends Thread {
    private String name;

    public YieldThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println(name + i);
            if (i == 5) {
                Thread.yield();
            }
        }
    }
}

每次运行的结果都可能会有偏差,但是注意线程一5和线程二5之后的执行结果。
另一种理解:在网上还存在另一种理解,当调用Thread.yield()函数后,当前线程会被停止,继而其他线程会争夺cpu的控制权,因此有可能是当前线程获得执行,也可能其他线程获得执行. 根据官方文档和Thinking In Java上的讲解,可以确定这种理解是错误的.当调用Thread.yiele()时,没有任何机制可以保证当前线程一定会被停止

总结

可以看出,不管优先级和yield()函数都是试图控制线程的顺序执行.但是我们需要注意的一点是,在java中没有任何机制可以保证线程的执行顺序,两种做法只不过是增加了线程之间切换的几率而已.

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值