深入理解synchronized

public class SynchronizedTest implements Runnable {
    private static int count = 0;

    public static void main(String[] args) {
        SynchronizedTest test = new SynchronizedTest();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(test);
            thread.start();
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("count=" + count);
    }


    /**
     * 字节码
     0 ldc #2 
     2 dup
     3 astore_1
     4 monitorenter
     5 iconst_0
     6 istore_2
     7 iload_2
     8 ldc #21 <1000000>
     10 if_icmpge 27 (+17)
     13 getstatic #17 
     16 iconst_1
     17 iadd
     18 putstatic #17 
     21 iinc 2 by 1
     24 goto 7 (-17)
     27 aload_1
     28 monitorexit
     29 goto 37 (+8)
     32 astore_3
     33 aload_1
     34 monitorexit
     35 aload_3
     36 athrow
     37 return
     */
    //synchronized的实现原理,查看run方法的字节码后,可以看到在12,20,28多出了monitorenter monitorexit
    //表示在执行到代码块的地方,首先需要获取到对象的监视器monitor,才可以执行代码。而这个获取的过程是互斥,即同一时刻只能有一个线程可以获取到
    //当代码块执行完毕后会释放monitor。并通知其他等待队列中的线程来竞争获得这个监视器。
    //上述字节码中28行再次出现了monitorexit,而没有出现monitorenter获取锁的指令,这是锁的重入性。即在同一锁的过程中,线程不需要再次获得同一把锁
    //synchronized先天具有重入性。每个对象都会拥有一个计数器,获得monitor计数器+1 释放后monitor计数器-1
    //当A线程获得motinor后其他线程会进入等待队列当监视器被释放后等待队列中的线程才有机会获得锁
    public void run() {
        synchronized (SynchronizedTest.class) {
            for (int i = 0; i < 1000000; i++)
                count++;
        }
    }
}

你可能感兴趣的:(深入理解synchronized)