«Это пятый день моего участия в первом испытании обновлений 2022 года. Подробную информацию о мероприятии см.:Вызов первого обновления 2022 г.".
оптимизация блокировки
В процессе блокировки jvm будет использовать такие методы оптимизации, как спин, самоадаптация, устранение блокировок и огрубление блокировок, чтобы повысить эффективность выполнения кода.
Спин-блокировки и адаптивный спин
Большинство процессоров в настоящее время являются многоядерными процессорами.Если на многоядерном процессоре параллельно выполняются два или более потока, мы можем позволить ожидающему потоку не уступать время выполнения процессора. Установите тайм-аут ожидания, чтобы увидеть, может ли поток быстро снять блокировку.В течение периода ожидания можно выполнить пустой цикл, чтобы текущий поток продолжал занимать квант времени ЦП. Это называетсяблокировка спина.
в JVM через+XX:UseSpinning
Чтобы включить блокировку вращения, она у нас включена по умолчанию после JDK1.6. Поскольку использование спин-блокировок может привести к тому, что конкуренты по блокировкам будут занимать больше процессорного времени, JVM задает параметр для количества спинов. мы можем пройти-XX:PreBlockSping
внести изменения (по умолчанию 10 раз).
Переходы состояний смещенных блокировок, облегченных блокировок и отношения объекта Mark Word преобразуются, как показано на следующем рисунке:
снятие блокировки
Устранение блокировки относится к стратегии оптимизации, реализуемой компилятором «точно в срок» виртуальной машины, когда он обнаруживает, что определенный фрагмент кода, который необходимо синхронизировать, не может конкурировать с общими данными, и реализует его. Основное суждение об устранении блокировок основано на анализе побегов. Если вы судите по фрагменту кода, что все данные в куче не будут ускользать и к ним будут обращаться другие потоки, то относитесь к ним как к данным в стеке, считайте их приватными, и нет необходимости в блокировках синхронизации.
Ниже приведен пример добавления трех строк x, y, z, не являющихся ни исходным кодом, ни логически синхронизированным.
public String concatStr(String x, String y, String z) {
return x + y + z;
}
String является неизменяемым классом, и связывание символов всегда генерирует новый объект String, поэтому компилятор Javac автоматически оптимизирует связывание строк.До jdk5 связывание строк было преобразовано вStringBuffer
; после того, как jdk5 будет преобразован вStringBuilder
объект непрерывныйappend()
Operation, посмотрим на результат декомпиляции после javac:
public String concatStr(String x, String y, String z) {
StringBuilder sb = new StringBuilder();
sb.append(x);
sb.append(y);
sb.append(z);
return sb.toString();
}
Посмотрим еще разjavap
Декомпилированный результат:Вы можете беспокоиться здесьStringBuilder
Существуют ли проблемы с потокобезопасностью для операций, которые не являются потокобезопасными? Ответ здесь нет,x + y + z
Оптимизация работыПосле анализа побегаПосле этого его динамический диапазон ограничиваетсяconcatStr
В методе, то есть текущем фактическом выполненииStringBuilder
операция вconcatStr
внутри метода,Другие внешние потоки не могут получить доступ
StringBuffer buffer = new StringBuffer();
/** 锁粗化 */
public void append(){
buffer.append("aaa").append(" bbb").append(" ccc");
}