详解synchronized关键字

一、synchronized的基本知识

首先要明白,synchronized关键字锁的是对象,而不是代码块,每个对象的对象头中的markword中有两个二进制位用于标记对象的锁状态,每个对象还有一个监视器Monitor用于实现锁。
监视器Monitor的实现及原理

二、synchronized的使用

2.1、修饰普通方法

	/**
     * synchronized使用方式1:修饰普通方法
     * 锁的是当前对象 this
     */
    public synchronized void way1() {
        System.out.println("synchronized使用方式1:修饰普通方法");
    }

2.2、修饰静态方法

	/**
     * synchronized使用方式2:修饰静态方法
     * 锁的是类的Class对象
     */
    public static synchronized void way3() {
        System.out.println("synchronized使用方式2:修饰静态方法");
    }

2.3、修饰代码块

	/**
	* 创建一个对象,用于加锁
	* 对象相当于一把锁
	*/
	private final Object o = new Object();
	/**
     * synchronized使用方式3:修饰代码块
     * 传入对象是this的话,锁的是当前对象
     * 传入对象o的话,锁的是对象o
     * 传入HowToUseSynchronized.class对象的话,锁的是类的Class对象
     */
    public synchronized void way2() {
        // 传入对象是this的话,锁的是当前对象
        // 传入对象o的话,锁的是对象o
        // 传入HowToUseSynchronized.class对象的话,锁的是Class对象
        // synchronized (this) {
        // synchronized (HowToUseSynchronized.class) {
        synchronized (o) {
            System.out.println("synchronized使用方式3:修饰代码块");
        }
    }

在这里插入图片描述

三、synchronized的锁升级

JDK1.6之后,为了减少获得锁和释放锁带来的性能消耗,synchronized引入了锁升级,并不是一开始就使用操作系统级别的重量级锁。

3.1、无锁

一个对象锁没有线程获取过时,处于无锁状态。

3.2、偏向锁

一个对象锁第一次有线程获取时,对象头中的MarkWord会记录线程的ID(记为线程1),此时处于偏向锁状态。
当有线程(记为线程2)再次尝试获取该对象锁时,先会判断是否为MarkWord中记录的线程ID,若是,线程2可直接获得对象锁,执行同步代码块;若不是,则需查看线程1当前是否存活,若线程1已运行结束,则将MarkWord中的线程ID设置为线程2,若线程1还存活,那么查看线程1的栈帧信息,如果线程2不需要继续持有该对象锁,那么将MarkWord中的线程ID设置为线程2,如果线程1需要继续持有该对象锁,则升级为轻量级锁(自旋锁)。

3.3、轻量级锁 - 自旋锁CAS

自旋锁,即未获取到对象锁的线程循环尝试获取锁(默认尝试10次),如果在这循环尝试期间,持有对象锁的线程刚好释放了锁,那么正在自旋获取锁的线程就有机会获取到对象锁。如果循环尝试没有成功,那么会升级为重量级锁。

3.4、重量级锁

操作系统级别的锁,如lock指令等。

四、synchronized的使用注意事项

  • synchronized锁定的对象不能是String常量。当两个毫不相干的同步代码块都需要获取字符串“1234”常量才能允许,由于字符“1234”在常量池中只有一份,那么这两个毫不相干的同步代码块会相互影响,甚至产生死锁
  • synchronized锁定的对象也不能是Integer、Long等基本数据类型的包装类,虚拟机缓存-128~127的整型包装类对象,所有在-128 ~ 127之间的整型包装类对象是同一个对象
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

it00zyq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值