本篇来聊下线程让步-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.