synchronized

synchronized 使用场景
  • synchronized 作用在方法上,锁对象是当前实例

  • synchronized 作用在静态方法上,锁对象是当前类对象

  • synchronized 作用在代码快上,锁对象需要提供锁的对象

java6 以后 对synchronized 进行了优化,引入多种锁状态,无锁、偏向锁、轻量级锁、重量级锁 锁可升级,不可降级(除偏向锁退回到 无锁状态)
  • thread1 获取对象的monitor后就进入对象running 状态,此时没有其他 thread 竞争情况下,对象头中的mark word 锁标记位 为偏向锁、并记录 占有 锁的线程id。
  • thread1 占有锁的控制权时,thread2 对锁的争取时,会判断对象头总记录的 线程id 是否存活,如果不存活 则会发生锁降级(偏向锁 -> 无锁)
  • thread1 和 thread2 同时争抢锁的控制权,上锁对象头中的 mark word 锁标记位 位轻量级锁,同时为获得 锁的thread 在自旋 + cas 等待另一个线程对锁的释放,此时 thread3 也加入到争抢锁的活动中来,那么 锁将升级为 重量级锁,并且没有获取到锁的线程,将放弃 自旋,进入阻塞队列,synchronized 的阻塞队列,是不公平的(并不是 先入先出模式)

cas + 线程自旋 优点:减少线程 唤醒带来的资源浪费。 使用场景:线程占有锁的过程比较短

使用ReentrantLock的注意点ReentrantLock 和 synchronized 不一样,需要手动释放锁,所以使用 ReentrantLock的时候一定要手动释放锁,并且加锁次数和释放次数要一样(不一致会导致死锁)

非公平锁比公平锁 效率高,高并发场景

ReentrantLock类实现了Lock接口,并提供了与synchronized相同的互斥性和内存可见性,它的底层是通过AQS来实现多线程同步的。与内置锁相比ReentrantLock不仅提供了更丰富的加锁机制,而且在性能上也不逊色于内置锁(在以前的版本中甚至优于内置锁)。

ReentrantLock 和 synchronized 区别
reentrantLock 是基于jdk层面的锁,synckronized 是jvm层面的
reentrantLock是可中断、可以限定获取锁的时间 而synchronized 是不行的
reentrantLock 需要手动释放锁
reentrantLock 支持公平和非公平锁,synckronized 支持非公平锁
synckronized 支持锁升级,认为是乐观锁,reentrantLock 是悲观锁,不支持锁升级
synckronized 阻塞队列是栈结构,reentrantLock 阻塞队列是双向链表
reentrantLock 出队、入队、加锁、解锁 都由AQS(AbstractQueuedSynchronizer) 完成

也可采用自旋 + cas 防止线程并发,带来的隐患。缺点:在自旋过程 cpu在空转

wait、notify 需使用在synchronized 控制的代码快中,作用是 只有线程获取当前对象的 monitor 才能对加锁对象进行 wait操作,或者对wait 导致等待的线程 进行唤醒(notify/notifyall)操作
wait 会释放线程对锁的持有,使其他线程可以执行synchronized 控制的代码快
wait 状态的线程不允许中断(Interrupted)操作

//  在没有获取锁的线程 直接调用 object 类下的 wait 或 notify 方法,导致的问题
Exception in thread "main" java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值