在Java中使用Thread.yield()的作用是什么?

3

我有以下类:

package net.adjava.multithreading;

public class MyResource {

    private int a;



    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

}

package net.adjava.multithreading;

public class Thread1 extends Thread {
    MyResource m;

    public Thread1(MyResource m) {
        super();
        this.m = m;
    }

    @Override
    public void run() {
        System.out.println("Current Thread name1 :"
                + Thread.currentThread().getName());

        for (int i = 0; i < 10000; i++) {
            m.setA(i);
            System.out.println("Set method sets the value of a as: " + i);
            System.out.println("Current Thread name1 :"
                    + Thread.currentThread().getName());

            Thread.yield();

        }
    }
}

package net.adjava.multithreading;

public class Thread2 extends Thread {

    MyResource m;
    public Thread2(MyResource m) {
        super();
        this.m = m;
    }
    @Override
    public void run() {
        System.out.println("Current Thread name2 :" + Thread.currentThread().getName());

        for (int i = 0; i < 100; i++) {

            System.out.println(" value of a as per getter method is :"
                    + m.getA());
            System.out.println("Current Thread name2 :" + Thread.currentThread().getName());


        }
        System.out.println("waiting for thread to end");

    }

}

package net.adjava.multithreading;

public class ThreadExecutionPoint {

    public static void main(String args[])
    {
        System.out.println("Current Thread name main :" + Thread.currentThread().getName());

        MyResource m = new MyResource();
        Thread1 th1 = new Thread1(m);
        Thread2 th2 = new Thread2(m);
        th1.start();
        th2.start();

    }
}

我正在尝试理解在上述类中使用yield()的目的。在尝试此示例之前,我所知道的关于yield()的只有它可以暂停调用它的线程。因此,为了测试它,我在Thread1类中使用了yield()方法。基本上,根据我的理解,Thread1应该执行一次for循环,然后暂停并等待其他线程完成。但输出显示出不同的结果。输出显示首先执行Thread1,然后是Thread2。请问有人能纠正我错过的地方吗?或者我的对yield()的理解有问题吗?

yield 不会强制其他线程执行任务。它只会在有其他线程正在尝试获取 CPU 时间时,强制调用线程让出 CPU 时间给其他线程执行任务。看起来 thread1 在完成所有任务之前就已经结束了,或者调度程序选择让 thread1 先完成。 - jonhopkins
我对yield()方法还有一个疑惑。由于main()也是一个线程,所以在上面的例子中,我总共有3个线程,即thread1、2和main()。现在,如果我在thread1上调用yield(),是否可能导致main()线程在thread1结束之前停止,从而导致程序结束? - noone
我相信程序在所有线程被销毁之前不会退出。https://dev59.com/XF_Va4cB1Zd3GeqPPhBs#8784366 - jonhopkins
2个回答

4
文档说明了与yield方法有关的内容:

使当前正在执行的线程对象暂时暂停并允许其他线程执行。

虽然可能发生这种情况,但不能保证被选择处理的线程不是相同的线程。
就像几乎所有与线程有关的事情一样,不要依赖它,因为您期望的功能不能得到保证。

我对yield()方法还有一个疑惑。由于main()也是一个线程,所以在上面的例子中,我总共有3个线程,即thread1、2和main()。现在,如果我在thread1上调用yield(),是否可能导致main()线程在thread1结束之前停止,从而导致程序结束? - noone
理论上,当没有更多的“非守护线程”处于活动状态时,执行会停止,因此如果已经开始处理并且不是守护线程,则您的程序不应该结束。 - Rodrigo Sasaki

3
我引用自这里
这个静态方法主要用于通知系统当前线程愿意“放弃CPU”一段时间。一般的想法是: 线程调度程序将选择一个不同的线程来运行,而不是当前的线程。 然而,yielding如何由线程调度程序实现在平台之间有所不同。一般来说,您不应该依赖它以某种特定的方式运行。不同的事情包括: 在yielding后,线程何时再次获得运行机会; 线程是否放弃其剩余时间片。
简而言之,您永远不知道线程执行何时会重新启动。

我对yield()方法还有一个疑惑。由于main()也是一个线程,所以在上面的例子中,我总共有3个线程,即thread1、2和main()。现在,如果我在thread1上调用yield(),是否可能导致main()线程在thread1结束之前停止,从而导致程序结束? - noone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接