首页 新闻 会员 周边 捐助

java8 偏向锁里面的批量重偏向为什么未到阈值就已经偏向?

0
[待解决问题]

public static void main(String[] args) {

       // 当偏向锁侧撤销操作达到一定的阈值后会批量重偏向
     Vector<Object> list = new Vector<>();
     Thread t1 = new Thread(() -> {
        for (int i = 0; i < 25; i++) {
            Object obj = new Object();
            list.add(obj);
            synchronized (obj){
                System.out.println("t1线程的 index = "+ i+" mark word: "+ ClassLayout.parseInstance(obj).toPrintableSimple());
            }
        }
        synchronized (list){
            list.notify();
        }
    }, "t1");
    Thread t2 = new Thread(() -> {
        synchronized (list){
            try {
                list.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 25; i++) {
            Object obj = list.get(i);
          //  System.out.println("t2线程 第一次 的 index = "+ i+" mark word: "+ ClassLayout.parseInstance(obj).toPrintableSimple());
            synchronized (obj){
                System.out.println("t2线程第二次 的 index = "+ i+" mark word: "+ ClassLayout.parseInstance(obj).toPrintableSimple());
            }
          //  System.out.println("t2线程第三次 的 index = "+ i+" mark word: "+ ClassLayout.parseInstance(obj).toPrintableSimple());
        }
    }, "t2");
    t1.start();
    t2.start();
}

下面是返回的结果,t2在 index =14的时候就已经偏向了而不是在默认的19 ,
我这里面是系统默认值
intx BiasedLockingBulkRebiasThreshold = 20 {product}
intx BiasedLockingBulkRevokeThreshold = 40

下面的结果在 t2线程第二次 的 index = 14 的时候就已经变为偏向锁

t1线程的 index = 0 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00000000 00000101 (biased: 0x0000000052137040; epoch: 0; age: 0)
.....
t1线程的 index = 24 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00000000 00000101 (biased: 0x0000000052137040; epoch: 0; age: 0)

t2线程第二次 的 index = 0 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 1 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 2 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 3 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 4 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 5 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 6 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 7 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 8 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 9 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 10 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 11 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 12 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 13 mark word: 00000000 00000000 00000000 01000111 00101110 10011111 11110010 10110000 (thin lock: 0x000000472e9ff2b0)
t2线程第二次 的 index = 14 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 15 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 16 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 17 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 18 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 19 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 20 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 21 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 22 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 23 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)
t2线程第二次 的 index = 24 mark word: 00000000 00000000 00000001 01001000 01001101 11000001 00010001 00000101 (biased: 0x0000000052137044; epoch: 0; age: 0)

Process finished with exit code 0

烟雨蒙尘的主页 烟雨蒙尘 | 菜鸟二级 | 园豆:202
提问于:2023-01-30 14:19
< >
分享
所有回答(1)
0

在Java 8 中,偏向锁引入了一种新的机制,称为“批量重偏向”(Bulk Rebiasing)。这个机制的主要目的是优化偏向锁的性能,特别是在程序启动时和长时间运行之后的场景。

批量重偏向机制的基本思想是,在一段时间内,如果一个对象被重复访问,那么它会从轻量级锁或无锁状态转换为偏向锁状态。这样,就可以避免频繁地进行偏向锁的撤销和重偏向,从而提高程序的性能。

Java 8 中的批量重偏向机制是通过一个阈值来实现的。当一个线程访问一个偏向锁对象时,它会检查该对象的偏向锁是否已经达到了重偏向的阈值。如果没有达到阈值,那么线程会直接获取该对象的偏向锁。否则,线程会放弃偏向锁,使该对象恢复到无锁状态,并重新进入轻量级锁状态。

那么为什么会出现未到达阈值就已经偏向的情况呢?可能有以下几个原因:

对象被多个线程频繁地访问,导致偏向锁状态无法稳定保持,从而导致偏向锁的撤销和重偏向。

阈值设置得过小,导致对象无法达到重偏向的阈值就被重新偏向。

在某些场景下,可能会出现偏向锁状态的竞争,导致偏向锁的撤销和重偏向。

总之,批量重偏向机制的实现是比较复杂的,它涉及到对象访问的频率、阈值的设置、竞争情况等多个因素。因此,在使用偏向锁时,我们需要根据具体的场景进行合理的设置和调整,以达到最优的性能。

心若向阳花自开 | 园豆:290 (菜鸟二级) | 2023-03-08 14:49
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册