synchronized底层实现

2020-11-08  本文已影响0人  叫我C30混凝土

synchronized

//代码
private void increment(){ 
        synchronized(this){
            counter++;
        }
    }

//字节码
private increment()V
    TRYCATCHBLOCK L0 L1 L2 null
    TRYCATCHBLOCK L2 L3 L2 null
   L4
    LINENUMBER 22 L4
    ALOAD 0
    DUP
    ASTORE 1
    MONITORENTER //占有锁(监视器)
   L0
    LINENUMBER 23 L0
    ALOAD 0
    GETFIELD com/Coordinator$MyThread.i : Ljava/lang/Integer;
    ASTORE 2
    ALOAD 0
    ALOAD 0
    GETFIELD com/Coordinator$MyThread.i : Ljava/lang/Integer;
    INVOKEVIRTUAL java/lang/Integer.intValue ()I
    ICONST_1
    IADD
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    DUP_X1
    PUTFIELD com/Coordinator$MyThread.i : Ljava/lang/Integer;
    ASTORE 3
    ALOAD 2
    POP
   L5
    LINENUMBER 24 L5
    ALOAD 1
    MONITOREXIT  // 退出锁(监视器)
   L1
    GOTO L6
   L2
   FRAME FULL [com/Coordinator$MyThread java/lang/Object] [java/lang/Throwable]
    ASTORE 4
    ALOAD 1
    MONITOREXIT
   L3
    ALOAD 4
    ATHROW
   L6
    LINENUMBER 25 L6
   FRAME CHOP 1
    RETURN
   L7
    LOCALVARIABLE this Lcom/Coordinator$MyThread; L4 L7 0
    MAXSTACK = 3
    MAXLOCALS = 5

//方法2.synchronized 在方法上
private synchronized static void doSomething(){
            i++;
        }

// 反例:
static class MyThread extends Thread{
        private synchronized void doSomething(){

        }
        @Override
        public void run(){
            doSomething();
            System.out.println(123);
        }
    }

    public static void main(String[] args) {
        // 开启了四个线程,但synchronized 方法锁住的是每个实例自己的doSomething();所以synchronized 锁并没有用;
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
对象头.png

锁粗化与锁消除

public static void main(String[] args) {
        increment();
    }

    private static void increment(){
        // monitorenter
        for (int i = 0 ;i <10; i++) {
            foo();
        }
         // monitorexit
    }

    // foo()频繁的加锁解锁,编译器就会把他优化成更大范围的锁
    private static synchronized void foo() {
        System.out.println("");
    }
上一篇下一篇

猜你喜欢

热点阅读