synchronized详解

1.synchronized的作用

  1. 原子性:确保线程互斥的访问同步代码;
  2. 可见性:保证共享变量的修改,能够及时可见,其实java内存模型中对一个变量unlock操作之前必须同步到主内存中,对一个变量进行lock操作,则会清除工作内存中该变量的值,在执行引擎获取该变量之前,需要从主内存中重新load或assign操作重新初始化值来实现的;
  3. 有序性:有效的禁止指令重排序,一个unlock操作先行发生(happen-before原则,详情见JSR133协议)后面对同一个锁的lock操作。

2.synchronized的使用

synchronized可使用在代码块和方法中,不同的使用方法,被锁的对象也有所不同,具体如下表:

分类被锁对象
实例方法类的实例对象
静态方法类对象
实例对象类的实例对象
class对象类对象
任意Object对象实例对象Object

3.synchronized的原理

1.同步代码块
通过javap分析同步代码块代码的汇编语言,可以明确的看到,synchronized的语义底层是通过monitor的对象来完成的,其实wait和notify等方法也是通过monitor对象来实现的,所以只有同步代码块中才能执行这些方法,否则将抛java.lang.IllegalMonitorStateException异常;

在这里插入图片描述

2.同步方法
常量池中多了ACC_SYNCHRONIZED标识,JVM通过该标识符来实现方法的同步:当方法被调用时,判断标识符是否被设置,如设置了,线程先获取monitor,获取成功后才能执行方法体,方法执行完成后释放monitor,在执行期间,其他线程无法获取同一个monitor对象;
两种同步方法本质上没有区别,只是方法的同步是一种隐式的方式来实现的,无需通过字节码来完成。

在这里插入图片描述

4.synchronized的优化

从JDK5引入了现代操作系统新增加的CAS原子操作(JDK5并没有对synchronized进行优化,而是体现在JUC中,所以该版本
concurrent包有更好的性能);
从JDK6开始,对synchronized的实现机制进行了较大的调整:
1.包含JDK5引进的CAS自旋、自适应CAS自旋
2.锁消除
3.锁粗化
4.偏向锁
5.轻量级锁
(synchronized的四种状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态)

5.死锁

死锁是两个或更多的线程堵塞着等待其它处于死锁状态的线程所持有的锁;
死锁通常发生在多个线程同时但不同顺序请求同一组锁的时候。

public class DeadLock{
	/** A锁 */
    private static String A = "A";

    /** B锁 */
    private static String B = "B";

    public static void main(String[] args) {
        new DeadLock().deadLock();
    }

    public void deadLock() {

        /**
         * 先获取A锁再获取B锁
         */
        Thread t1 = new Thread(() -> {
            synchronized (A) {
                try {
                    // 获取A锁后休眠2s
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (B) {
                    // 获取B锁
                    System.out.println("thread1...");
                }
            }
        });

        /**
         * 先获取B锁再获取A锁
         */
        Thread t2 = new Thread(() -> {
            synchronized (B) {
                try {
                    // 获取B锁后休眠2s
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (A) {
                    System.out.println("thread2...");
                }
            }
        });

        t1.start();
        t2.start();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值