java并发编程之二:Synchronized及其实现原理

2020-06-18  本文已影响0人  ModestStorm

Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作用主要有三个:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见(3)有效解决重排序问题。从语法上讲,Synchronized总共有三种用法:

(1)修饰普通方法
(2)修饰代码块
(3)修饰静态方法


1.修饰普通方法:当前对象的监视器monitor是锁对象

//获取的是当前对象的监视器锁
    public synchronized void method1(){
        System.out.println("method1");
    }

2.修饰代码块:当前对象是synchronized参数修饰的锁对象

  //获取的是当前对象的监视器锁
    public void method2(){
        synchronized (this){
            System.out.println("method2");
        }
    }

3.修饰静态方法:当前锁对象是Class字节码对应的monitor监视器锁

 public synchronized static void method3(){
        System.out.println("method3");
    }

synchronized的实现原理

使用javap反编译字节码查看:

 javap -c SynchronizedTest.class
javap命令

monitorenter

每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

monitorexit

指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个 monitor 的所有权。
通过对字节码反编译,应该能很清楚的看出Synchronized的实现原理,Synchronized的语义底层是通过一个monitor的对象来完成,其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调用wait/notify等方法,否则会抛出java.lang.IllegalMonitorStateException的异常的原因。

上一篇下一篇

猜你喜欢

热点阅读