Thread.yield()函数

张贤 2020年03月14日 92次浏览

当调用 Thread 中的 yield() 函数时,会给线程调度器一个当前线程愿意让出 CPU 使用权的提示,但是线程调度器可能会忽略这个暗示。也就是线程调度器可能会继续执行该线程,也可能暂停这个线程。
如下例子:

public class YieldDemo {
    public static void main(String[] args) {
        Runnable yieldTask = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()+i);
                    if (i==5){
                        //当 i==5 时,提示调度器当前线程可以让出 CPU
                        Thread.yield();
                    }
                }
            }
        };
        Thread t1=new Thread(yieldTask,"threadA");
        Thread t2=new Thread(yieldTask,"threadB");
        t1.start();
        t2.start();
    }
}

i==5时,提示调度器当前线程可以让出 CPU,但实际上可能会执行到i==6或者i==7时才会让出 CPU,发生线程切换。


但是yield()方法并不会对占有锁的线程造成影响。如果一个线程没占有锁,调用Thread.yield()方法并不会让出 CPU,也不会让出锁,直到线程执行完成或者释放锁。

public class WaitSleepDemo {
    public static void main(String[] args) {
        Object lock = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread A is waiting to get lock");
                synchronized (lock) {
                    System.out.println("Thread A get lock");
                    try {
                        Thread.sleep(20);
                        System.out.println("Thread A do wait method");
                        //线程 A 释放锁,此时线程 B 可以拿到锁,进入 synchronized 代码块
                        lock.wait(1000);
                        //这一句代码会阻塞,直到线程 B 完成后会释放锁,此时线程 A 拿到锁,执行这一句
                        System.out.println("Thread A is done");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        //睡眠 20ms 后,在启动 B 线程,此时线程 A 已经获取了锁
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread B is waiting to get lock");
                //线程 B 阻塞在这里,直到线程 A 执行 lock.wait(1000); 时,线程 B 才继续往下执行
                synchronized (lock) {

                    System.out.println("Thread B get lock");
                    try {
                        System.out.println("Thread B is sleep");
                        Thread.sleep(10);
                        lock.notifyAll();
                        //这里调用 yield() 方法不会让出 CPU,直到该线程执行完成释放锁才会让出 CPU
                        Thread.yield();
                        Thread.sleep(2000);
                        System.out.println("Thread B is Done");

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

在线程 B 中调用 yield() 方法不会让出 CPU,直到该线程执行完成释放锁才会让出 CPU