Невозможно воспроизвести закрепление виртуального потока (jdk 21), но MySQL не так параллелен, как должен быть.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Невозможно воспроизвести закрепление виртуального потока (jdk 21), но MySQL не так параллелен, как должен быть.

Сообщение Anonymous »

Документ jdk 21 о виртуальных потоках (далее «VT»)
(https://docs.oracle.com/en/java/javase/ ... reads.html)
довольно ясно, что синхронизированный блок вызывает закрепление потока, или собственные методы, или...
Все началось с другого вопроса SO о MySQL и виртуальных потоках (Can Virtual Threads улучшать запрос к базе данных на Java?), и это показало, что VT не распараллеливает операторы mysql должным образом (в драйверах до 9.0.0, например 8.4). Хотя я наверняка смогу воспроизвести это в ката.... Давайте попробуем!
Я создал 12 задач по 1 потоку на задачу, каждая задача выполняет 3 блокирующая операция 1000 мс внутри синхронизированного блока. На каждую задачу должно уйти 3x1000 мс = 3 секунды. По крайней мере, в ветках платформы. И эти потоки платформы всегда делают это предсказуемо.
Я написал варианты блокирующих операций, такие как Object.wait() внутри ssynced, как простой Thread.sleep() (синхронизированный и нет). , как условие ReentrantLock.await() и как входной поток сокета read() (синхронизированный и нет). Мои деньги были в сети прочитаны, так как это сделал драйвер mysql. Кроме того, из исходного кода jdk мы видим, что object.wait() и thread.sleep() стали дружественными к VT. Я даже попробовал, но удалил настройку Pipe Input/Output Stream, потому что все они основаны на той же предыдущей синхронизации в памяти.
На VT, согласно документу, я должен ожидать синхронизированного и собственного методы, но не повторные блокировки, чтобы занять больше времени, но это будет зависеть от того, сколько потоков несущей существует... Они не говорят.
(ОБНОВЛЕНИЕ: на самом деле позже я обнаружил, что есть столько же, сколько ядер, но дополнительных можно создать до 256).
Если потоков несущих ровно столько, сколько ядер, то у меня есть 4 несущих. Если бы я действительно закрепил VT, я должен был бы ожидать, что мои задачи будут выполняться только по 4 одновременно, и все задачи завершатся к отметке в 9 секунд.
Я хотел это доказать. Поэтому я написал этот сложный тест ниже.
И мне не удалось закрепить ни одну несущую цепочку; (сначала: см. мой собственный ответ) 12 задач заканчиваются почти одновременно на отметке 3 секунды.< /p>
Что еще интереснее, я запустил 12 потоков, но в какой-то момент было использовано 14 несущих.
(ОБНОВЛЕНИЕ: это ожидаемые дополнительные несущие после нахождения лучшего документа: «Захват Поток ОС компенсируется временным добавлением потока-носителя в планировщик. br />Чтобы увидеть идентификатор переносимого потока, я сначала использовал JNA, чтобы получить ядро ​​32 GetCurrentThreadId(). Позже я использовал вызов внешней функции (FFI), как предложил комментатор. С тех пор я удалил этот код JNA.
Я не буду повторять исходный код вопроса, поскольку он устарел и многое другое, даже если вы тоже не прочитаете ответ.
Мне очень хотелось узнать, как старый драйвер mysql 8.4 может привязать носитель VT к точке снижения параллелизма и, в частности, как это исправить в драйвере 9.0.x, но мне не хотелось читать код mysql. сделать это. Казалось, что ката размером с один файл была в порядке.
(ОБНОВЛЕНИЕ: поэтому я нашел способ воспроизвести закрепление, см. ответ.)
(ОБНОВЛЕНИЕ: после ответа комментаторы отметили, что Java 24 будет реализовывать блоки и методы Synchronized() таким образом, чтобы VT могли отвязываться от потоков платформы.)

Подробнее здесь: https://stackoverflow.com/questions/792 ... llel-as-sh
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»