Как приоритеты потоков Java переводятся в приоритет потока ОС?

Как приоритеты потоков Java API (1–10) преобразуются в приоритеты уровня ОС, поскольку в большинстве ОС нет уровней приоритета потоков (с точки зрения числа), которые соответствуют этому.

Итак, помните, может ли быть сценарий, когда два или более потока с разными приоритетами в конечном итоге получат одинаковый приоритет на уровне ОС.

Пожалуйста, поясните, если в моем понимании есть какие-то исправления.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
9
0
4 886
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Поскольку мы говорим о потоках, я думаю, что они никогда не доходят до ОС напрямую. Приоритет, вероятно, является подсказкой JRE о том, как планировать процессорное время для каждого потока. Чтобы разобраться с вашим примером, должен быть какой-то алгоритм разрешения конфликтов.

По сути, это будет поверх приоритета процесса ОС, если только JRE не использует сторонние стандарты потоковой передачи, такие как POSIX, вместо того, чтобы реализовывать все внутренне.

Ответ принят как подходящий

Действительно, некоторые уровни приоритета могут соответствовать одному и тому же «собственному» уровню приоритета. Вот список (на основе кода точки доступа в OpenJDK 6):

Солярис

  • 1 ⇒ 0
  • 2 ⇒ 32.
  • 3 ⇒ 64.
  • 4 ⇒ 96.
  • 5-10 ⇒ 127.

Следует отметить, что в Solaris вы не можете повысить приоритет потока выше нормального, а только понизить его: значение приоритета 5 такое же, как и любое из более высоких значений.

Linux

  • 1 - 10 ⇒ 4 - -5 (значения nice)

Следует отметить, что в Linux разные приоритеты потоков в Java сопоставляются с разными значениями приоритета на собственном уровне.

Окна

  • 1-2 ⇒ THREAD_PRIORITY_LOWEST
  • 3–4 ⇒ THREAD_PRIORITY_BELOW_NORMAL
  • 5–6 ⇒ THREAD_PRIORITY_NORMAL
  • 7-8 ⇒ THREAD_PRIORITY_ABOVE_NORMAL
  • 9–10 ⇒ THREAD_PRIORITY_HIGHEST

У вас есть справочная информация для этого, и является ли это прямым отображением или эмуляцией, основанной на том, как ОС обрабатывает эти значения?

Dana the Sane 18.11.2008 07:16

Официально не документировано, но прочтите hotspot / src / os / {linux, solaris, win32} / vm / os_ {linux, solaris, wi‌ n32} .cpp в исходном коде OpenJDK (ищите java_to_os_priority) для значений. :-)

Chris Jester-Young 18.11.2008 07:21

Там же подробно описано: javamex.com/tutorials/threads/priority_what.shtml

Guillaume 10.11.2010 19:54

Вы правильно поняли - приоритеты потоков Java не точно соответствуют приоритетам потоков ОС.

В результате, если ваш алгоритм каким-либо образом полагается на детали сопоставления приоритетов потоков, он не работает, поскольку он будет варьироваться в зависимости от такого количества переменных. Обновление JRE или применение патча / пакета обновления к вашей ОС может, например, сломать его - и, конечно же, простая работа на другой ОС также будет иметь последствия.

За исключением очень необычных случаев, достаточно использовать только два приоритета - Нормальный и Низкий. Большая часть работы будет выполняться в обычном потоке. Низкий приоритет должен быть зарезервирован для потоков, которым нельзя позволять истощать потоки с нормальным приоритетом, а вместо этого просто поглощать и не использовать мощность процессора.

Хотя вы можете получить более мелкую детализацию, чем это, если захотите, вы должны знать, что любые более подробные детали, вероятно, будут потеряны на целевой платформе.

Я не уверен в Sun JVM в Linux. Написал быструю Java-программу для создания 10 потоков с каждым приоритетом и вычисления числа пи (метод 4 * atan (1)) с помощью BigDecimals по 500 000 раз каждый, присоединения к каждому потоку и отчета о затраченном времени для метода выполнения. Да, наверное, не лучший пример, но все же базовый.

$uname -r && grep bogomips /proc/cpuinfo
2.4.33.3
bogomips        : 4312.26
$java -version 2>&1 |head -1
Java version "1.6.0_01"
$javac T.java && java -Xmx32m T
1:3112
2:2636
3:2662
4:3118
5:2870
6:3319
7:3412
8:3304
9:3299
10:3069

Похоже, не такое уж большое отклонение, которого можно было бы ожидать! Это было на маленькой виртуальной машине Linux. Давайте на всякий случай попробуем это на реальной плите, этот блок тоже довольно активен со средними нагрузками редко ниже 7, давайте просто посмотрим, как мы планируем в такой среде:

$uname -r && grep bogomips /proc/cpuinfo
2.6.9-67.ELsmp
bogomips        : 3992.93
bogomips        : 3990.00
$java -version 2>&1 |head -1
java version "1.4.2_14"
$javac T.java && java -Xmx32m T
1:63200
2:64388
3:62532
4:58529
5:62292
6:64872
7:64885
8:64584
9:61653
10:61575

Хммм, здесь нет особой вариации, не знаю, преобразовал ли 1.4 потоки вообще. Попробуем окно Windows. Я знаю, что в Windows довольно агрессивная схема приоритета потоков. Все, что выше обычный, потребляет гораздо больше. Таким образом, давайте увеличим до 900000 итераций в каждом потоке:

C:\>java -version
java version "1.6.0_11"
C:\>java -Xmx32m T
1:12578
2:12625
3:11469
4:11453
5:10781
6:8937
7:10516
8:8406
9:9953
10:7391

Очень много того, что мы ищем, не так ли?

Другие вопросы по теме