1. Обзор
В этом уроке мы рассмотрим метод yield() in Поток класс.
Мы сравним его с другими идиомами параллелизма, доступными в Java, и в конечном итоге рассмотрим его практическое применение.
2. Краткий обзор урожайности()
Как следует из официальной документации, yield() предоставляет механизм для информирования “планировщика” о том, что текущий поток готов отказаться от текущего использования процессора, но он хотел бы вернуться как можно скорее.
“Планировщик” может свободно придерживаться или игнорировать эту информацию и фактически имеет различное поведение в зависимости от операционной системы.
В следующем фрагменте кода отображаются два потока с одинаковым приоритетом, выходящие после каждого расписания:
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() как часть объекта класса, join() как часть потока класса и sleep() как часть потока класса.
Давайте посмотрим, как они сравниваются с yield() .
3.1. yield() vs wait()
- В то время как yield() вызывается в контексте текущего потока, wait() может быть вызван только при явно приобретенной блокировке внутри синхронизированного блока или метода
- В отличие от yield() , для wait () можно указать минимальный период времени для ожидания перед любой попыткой запланировать поток снова
- С помощью wait() также можно разбудить поток в любое время с помощью вызова notify() или notifyAll() на соответствующем объекте блокировки
3.2. выход() против сна()
- В то время как yield() может сделать только эвристическую попытку приостановить выполнение текущего потока без гарантии того, когда он будет запланирован обратно, sleep() может заставить планировщик приостановить выполнение текущего потока по крайней мере на указанный период времени в качестве его параметра.
3.3. yield() vs join()
- Текущий поток может вызвать join() в любом другом потоке, что заставляет текущий поток ждать, пока другой поток умрет, прежде чем продолжить
- При необходимости он может указать период времени в качестве своего параметра, который указывает максимальное время, в течение которого текущий поток должен ждать перед возобновлением
4. Использование для получения урожая()
Как следует из официальной документации, редко необходимо использовать yield() и, следовательно, следует избегать, если не очень ясно с целями в свете его поведения.
Тем не менее, некоторые из способов использования yield() включают разработку конструкций управления параллелизмом, повышение быстродействия системы в программе с большим объемом вычислений и т. Д.
Однако эти методы должны сопровождаться подробным профилированием и сравнительным анализом, чтобы обеспечить желаемый результат.
5. Заключение
В этой краткой статье мы обсудили метод yield() в классе Thread и рассмотрели его поведение и ограничения через фрагмент кода.
Мы также изучили его сравнение с другими идиомами параллелизма, доступными в Java, и, наконец, рассмотрели некоторые случаи использования, когда yield() может быть полезен.
Как всегда, вы можете ознакомиться с примерами, приведенными в этой статье на GitHub .