简介synchronized关键词

synchronized的简介

能够保证多个线程条件下,在同一时刻只有一个线程能够执行该段代码。以达到并发安全的效果。比如常见的i++操作,如果不加锁的话可能会出现数据不一致。

synchronized的使用

Synchronized锁分为两类,一个是类锁,一个是对象锁。
在这里插入图片描述
synchronized的使用大概是上面的几种。

我们先从对象锁说起

对象锁,锁住的其实是实例化的对象,也就是我们new出来的实例。使用参考以下方法
在这里插入图片描述

上面两种锁都是锁住的是当前对象(this)。如何理解以下代码?
在这里插入图片描述
第1个线程和第2个线程存在锁竞争。而第1个和第3个以及第2个和第3个不存在锁竞争,即锁是无效的。
为什么呢?
第1个线程和第2个线程中的锁是SynchronizedTest1,而第三个线程的锁是SynchronizedTest2,所以第1个和第3个以及第2个和第3个不存在锁竞争。
总之一定要看清对象锁,锁住的对象是什么,如果多个线程使用的是“一把锁”那么就会存在锁竞争,如果使用的是“不同的锁”,那么锁会无效的

实例化对象不同,里面的锁也会不同,那么如何保证所有实例化的对象都拥有相同的锁?-----只能从类对象加锁

接着说类锁

类锁有两种添加方式,一种是class锁,一种是添加到静态方法中
在这里插入图片描述
加上类锁以后,所有实例化对象都拥有一把相同的锁。

关于锁,是否还有以下的疑惑

synchronized是“锁”?还是关键字?它到底作用在哪里?
锁是怎么作用在对象上的或者类上的?
synchronized锁到底“锁”住了什么?锁是什么?

synchronized是“锁”?还是关键字?它到底作用在哪里?

synchronized 仅仅是一个关键字,关键字的作用是给对象/类加锁,所以锁是加在对象上或者类上

锁是怎么作用在对象上的或者类上的?

  1. 如何作用在对象上?
  • 对象头的底层描述(未写)

对象由三部分组成:对象头、实例化数据、对齐填充。
以下是对象头中的markword
在这里插入图片描述
从这个图可以看出,可以通过修改对象头的标志位,让对象变成一个

所以synchronized修饰对象锁的时候,其实就是修改对象的对象头的markword里的重量级锁的标志位,使得将对象标记为一个重量级锁。
2. 如何作用在类上的?
类锁是加在类上的,而类的信息保存在jvm的方法区,并且整个jvm只有一份,方法区可以被所有的线程所共享。所以在类的信息上加入锁的标示,当多线程去访问每一个该类的实例化对象时,都会存在锁竞争,进而保证并发安全。

synchronized锁到底“锁”住了什么?锁是什么?

通过以上所说:
synchronized关键字,作用在类上,是类锁,那么锁就是这个类。锁住的是该类的所有实例化对象。
synchronized关键字,作用在对象上,是对象锁。那么锁就是这个对象。锁住的是该对象。

synchronized的底层原理

synchronized作用的地方就两个:同步方法块、同步方法
分析反编译之后的字节码,对于同步方法JVM采用的是ACC_SYNCHRONIZED标识符实现同步,对于同步代码块,JVM采用monitorenter和monitorexit来实现同步。不管是基于ACC_SYNCHRONIZED还是monitorenter、monitorexit都是基于Monitor实现的。参照monitor的原理

synchronized的性质

synchronized具有不可中断性 以及可重入性
可重入性依赖于monitor监视器里的计数器。其实也很好理解,获取了对象锁,那么这个对象的方法都可以访问,但是下面这个种情况不行。
在这里插入图片描述
这个也很好理解,对象锁(一个是son,一个是father)都一样,当然不可重入。这里面其实也暗含着死锁。

缺陷

  1. 效率低
    来源于不可中断和无法知道是否成功获取到锁。一个等待的线程如果获取不到锁就会一直等待,而不能做其他的事情。
  2. 不够灵活
    加锁和解锁的本质上是对象锁,所以不能够适用于分布式。
  3. 重量级锁
    重量级锁其实是相对于AQS自旋锁来说的,其重量级的原因在于,java线程是映射到操作系统的原生线程之上的,如果要阻塞一个线程或者唤醒,需要操作系统切换到内核态,因此状态切换需要花费处理器的时间,对于代码简单的同步块,状态转换消耗的时间可能比代码执行的时间长,所以说synchronized是java语言中的一个重量级的操纵。

类锁和对象锁的区别
彻底理解synchronized关键字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值