Я читаю исходный код, чтобы выяснить, как работает блокировка смещения. У меня есть вопрос о «массовых ребиа», которые произошли, когда количество отозванных экземпляров конкретного типа данных. и это увеличило бы поле эпохи в классе , чтобы сделать недействительными ранее удержанные смещения, облегчает массовую передачу владения смещением из одного потока в другой.
, и этот код следует, он был записан в файле biasedLocking. cpp:
for (; JavaThread *thr = jtiwh.next(); ) {
GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
for (int i = 0; i < cached_monitor_info->length(); i++) {
MonitorInfo* mon_info = cached_monitor_info->at(i);
oop owner = mon_info->owner();
markOop mark = owner->mark();
if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
// We might have encountered this object already in the case of recursive locking
assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
owner->set_mark(mark->set_bias_epoch(cur_epoch));
}
}
}
исходный код здесь . похоже, что все записи блокировки, которые заблокировали класс объекта, равны классу текущего объекта obj и все еще смещены. если какая-либо запись блокировки существует, ее владелец (объект блокировки) должен быть заблокирован с помощью облегченной блокировки (тонкой блокировки) потоком, что означает, что он должен был использовать блокировку смещения и отозван текущим владельцем, так почему этот код может найти блокировку объект использует шаблон смещения, но уже заблокирован с помощью тонкой блокировки?
обновлено в 2020/04/02
я пишу код для проверки:
package tech.lovelycheng.learning.javalang.jvmtest;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.concurrent.*;
import static java.lang.System.err;
public class BIASREVOKEDANDREBIASEDTest {
private static final Unsafe U;
private static final long OFFSET = 0L;
static {
try {
Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
U = (Unsafe) unsafe.get(null);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor();
Monitor monitor = new Monitor();
synchronized (monitor) {
err.println("monitor header: " + printBinaryHeader(monitor));
//reach biasedLockingBulkRebiasThreshold
for (int i = 0; i < 5; i++) { // to bulk rebias
Monitor s = new Monitor();
synchronized (s) {
}
threadPoolExecutor.submit(() -> {
synchronized (s) {
}
return null;
}).get();
}
}
err.println("monitor header: " + printBinaryHeader(monitor));// break point here
ss(threadPoolExecutor, monitor);
threadPoolExecutor.shutdown();
}
private static void ss(ExecutorService threadPoolExecutor, Monitor monitor) throws InterruptedException, ExecutionException {
threadPoolExecutor.submit(() -> {
synchronized (monitor) {
err.println("expect 101 at low end monitor header: " + printBinaryHeader(monitor));
}
}).get();
}
private static String printHeader(Object a) {
int word = U.getInt(a, OFFSET);
return Integer.toHexString(word);
}
private static String printBinaryHeader(Object a) {
int word = U.getInt(a, OFFSET);
return Integer.toBinaryString(word);
}
private static class Monitor {
// mutex object
public void fn() {
}
}
}
что я вижу через hsdb:
em ... основной поток просто выйдите из монитора, и без разногласий он наверняка будет использовать блокировку смещения. почему в его стеке есть basicObjectMonitor?
опция my jvm
-XX:+UseBiasedLocking
-XX:BiasedLockingStartupDelay=0
-Xlog:biasedlocking=trace
-XX:BiasedLockingBulkRebiasThreshold=5
-XX:BiasedLockingBulkRevokeThreshold=20
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1
версия моего jdk: 11.0.6