Java
Java多线程

Java多线程 04 - 线程让步

简介:yield()的作用是让步。它能让当前线程由运行状态进入到就绪状态,从而让其它具有相同优先级的等待线程获取执行权;但是并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到运行状态继续运行。

1. yield()介绍

yield()的作用是让步。它能让当前线程由运行状态进入到就绪状态,从而让其它具有相同优先级的等待线程获取执行权;但是并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到运行状态继续运行。

下面是yield()方法的示例:

  • public class YieldTest {
  • public static void main(String[] args) {
  • Thread thread1 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 1; i <= 10; i++) {
  • System.out.println(Thread.currentThread().getName() + " " + i);
  • // 在i为3、6、9的时候会进行让步
  • if (i % 3 == 0) {
  • System.out.println(Thread.currentThread().getName() + " yield");
  • Thread.yield();
  • }
  • }
  • }
  • }, "thread-1");
  • Thread thread2 = new Thread(new Runnable() {
  • @Override
  • public void run() {
  • for (int i = 1; i <= 10; i++) {
  • System.out.println(Thread.currentThread().getName() + " " + i);
  • // 在i为4、8的时候会进行让步
  • if (i % 4 == 0) {
  • System.out.println(Thread.currentThread().getName() + " yield");
  • Thread.yield();
  • }
  • }
  • }
  • }, "thread-2");
  • thread1.start();
  • thread2.start();
  • }
  • }

运行上述代码,某一次结果如下:

  • thread-1 1
  • thread-1 2
  • thread-1 3
  • thread-1 yield
  • thread-2 1
  • thread-2 2
  • thread-2 3
  • thread-2 4
  • thread-2 yield
  • thread-1 4
  • thread-1 5
  • thread-1 6
  • thread-1 yield
  • thread-2 5
  • thread-2 6
  • thread-2 7
  • thread-2 8
  • thread-2 yield
  • thread-1 7
  • thread-1 8
  • thread-1 9
  • thread-1 yield
  • thread-2 9
  • thread-2 10
  • thread-1 10

从运行结果中可以看到第4行线程thread-1进行了让步,第9行线程thread-2执行了让步,第13行thread-1进行了让步,第18行线程thread-2执行了让步,第22行thread-1进行了让步。

yield()需要注意的地方

yield()虽然可以让线程由运行状态进入到就绪状态;但是,它不一定会让其它线程获取CPU执行权(即,其它线程进入到运行状态),即使这个其它线程与当前调用yield()的线程具有相同的优先级。

2. yield()与wait()的比较

wait()的作用是让当前线程由运行状态进入等待(阻塞)状态的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开运行状态。它们的区别如下:

  • wait()是让线程由运行状态进入到等待(阻塞)状态,而yield()是让线程由运行状态进入到就绪状态。
  • wait()会让线程释放它所持有对象的同步锁,而yield()方法不会释放锁。

下面通过示例演示yield()是不会释放锁的:

  • class TestThread implements Runnable {
  • private Object lock;
  • public TestThread(Object lock) {
  • this.lock = lock;
  • }
  • @Override
  • public void run() {
  • synchronized (this.lock) {
  • for (int i = 1; i <= 10; i++) {
  • System.out.println(Thread.currentThread().getName() + " " + i);
  • // 在i为3、6、9的时候会进行让步
  • if (i % 3 == 0) {
  • System.out.println(Thread.currentThread().getName() + " yield");
  • Thread.yield();
  • }
  • }
  • }
  • }
  • }
  • public class YieldTest {
  • public static void main(String[] args) {
  • // 创建一个共享的对象作为锁
  • Object lock = new Object();
  • // 启动两个线程
  • new Thread(new TestThread(lock), "thread-1").start();
  • new Thread(new TestThread(lock), "thread-2").start();
  • }
  • }

上述代码中两个线程将共享同一把锁。某一次运行结果如下:

  • thread-1 1
  • thread-1 2
  • thread-1 3
  • thread-1 yield
  • thread-1 4
  • thread-1 5
  • thread-1 6
  • thread-1 yield
  • thread-1 7
  • thread-1 8
  • thread-1 9
  • thread-1 yield
  • thread-1 10
  • thread-2 1
  • thread-2 2
  • thread-2 3
  • thread-2 yield
  • thread-2 4
  • thread-2 5
  • thread-2 6
  • thread-2 yield
  • thread-2 7
  • thread-2 8
  • thread-2 9
  • thread-2 yield
  • thread-2 10

可以看到,在第4、8、12行thread-1进行了让步操作,但是并没有释放锁。