Краткое введение в Java Thread.yield ()

Краткое введение в Java Thread.yield ()

1. обзор

В этом руководстве мы рассмотрим методyield() в классеThread.

Мы сравним его с другими идиомами параллелизма, доступными в Java, и, в конце концов, исследуем его практическое применение.

2. Краткое содержаниеyield()

Как следует из официальной документации,yield() предоставляет механизм для информирования «планировщика» о том, чтоthe current thread is willing to relinquish its current use of processor but it’d like to be scheduled back soon as possible.

«Планировщик» может свободно придерживаться или игнорировать эту информацию и на самом деле имеет различное поведение в зависимости от операционной системы.

Следующий фрагмент кода отображает два потока с одинаковым приоритетом, уступая после каждого расписания:

public class ThreadYield {
    public static void main(String[] args) {
        Runnable r = () -> {
            int counter = 0;
            while (counter < 2) {
                System.out.println(Thread.currentThread()
                    .getName());
                counter++;
                Thread.yield();
            }
        };
        new Thread(r).start();
        new Thread(r).start();
    }
}

Когда мы пытаемся запустить вышеуказанную программу несколько раз, мы получаем разные результаты; некоторые из них упомянуты ниже:

Прогон 1:

Thread-0
Thread-1
Thread-1
Thread-0

Прогон 2:

Thread-0
Thread-0
Thread-1
Thread-1

Итак, как видите, поведениеyield() недетерминировано и также зависит от платформы.

3. Сравнение с другими идиомами

Существуют и другие конструкции, влияющие на относительное развитие потоков. Они включаютwait(),notify() иnotifyAll() как часть классаObject,join() как часть классаThread иsleep() в составе классаThread.

Посмотрим, как они соотносятся сyield().

3.1. yield() противwait()

  • Хотяyield() вызывается в контексте текущего потока,wait() может быть вызван только для явно полученной блокировки внутри синхронизированного блока или метода.

  • В отличие отyield(), для wait() возможно указать минимальный период времени ожидания перед любой попыткой снова запланировать поток.

  • С помощьюwait() также можно разбудить поток в любое время с помощью вызоваnotify() илиnotifyAll() для соответствующего объекта блокировки.

3.2. yield() противsleep()

  • Хотяyield() может сделать только эвристическую попытку приостановить выполнение текущего потока без гарантии того, когда это будет запланировано обратно,sleep() может заставить планировщик приостановить выполнение текущего потока на время как минимум указанный период времени в качестве параметра.

3.3. yield() противjoin()

  • Текущий поток может вызыватьjoin() в любом другом потоке, что заставляет текущий поток ждать, пока другой поток умрет, прежде чем продолжить

  • При желании в качестве параметра можно указать период времени, который указывает максимальное время, в течение которого текущий поток должен ждать, прежде чем возобновить работу.

4. Использование дляyield()

Как говорится в официальной документации, использованиеyield() возникает редко, и, следовательно, его следует избегать, если только не очень четко определены цели в свете его поведения.

Тем не менее, некоторые варианты использованияyield() включают разработку конструкций управления параллелизмом, повышение отзывчивости системы в программе с большим объемом вычислений и т. Д.

Тем не менее, эти способы использования должны сопровождаться подробным профилированием и сравнительным анализом для обеспечения желаемого результата.

5. Заключение

В этой краткой статье мы обсудили методyield() в классеThread и увидели его поведение и ограничения на фрагменте кода.

Мы также изучили его сравнение с другими идиомами параллелизма, доступными в Java, и, наконец, рассмотрели некоторые варианты использования, в которыхyield() может оказаться полезным.

Как всегда, вы можете ознакомиться с примерами из этой статьиover on GitHub.