Java中常见的锁及其应用场景

文章目录

  • 一.概念
  • 二.常见锁及其应用场景
      1. synchronized关键字
      • 1.1 应用场景
      • 1.2 特点
      1. ReentrantLock(可重入锁)
      • 2.1 应用场景
      • 2.2 特点
      1. ReadWriteLock(读写锁)
      • 3.1 应用场景
      • 3.2 特点
      1. OptimisticLock(乐观锁)
      • 4.1 应用场景
      • 4.2 特点
      1. PessimisticLock(悲观锁)
      • 5.1 应用场景
      • 5.2 特点
      1. CountDownLatch(倒计时锁存器)
      • 6.1 应用场景
      • 6.2 特点

一.概念

  1. 在Java中,锁是一种同步机制,用于控制多线程对共享资源的访问,以确保在任一时刻,只有一个线程能够执行业务代码。
  2. 锁的主要目的是防止多个线程同时修改共享资源,从而保证数据的一致性和线程安全。

二.常见锁及其应用场景

1. synchronized关键字

1.1 应用场景

  1. 用于方法或代码块上,保证同一时间只有一个线程能够执行当前代码。
  2. 每个对象都有一个监视器(monitor),当一个线程访问被synchronized修饰的方法或者代码块时,它必须先获得该对象的监视器.

1.2 特点

  1. 锁的粒度比较大,只能锁定整个方法或代码块.属于重量级锁.
  2. 可重入锁:一个线程获取了锁之后,可以再次获取这个锁而不会被阻塞,通常用于复杂的业务逻辑.
  3. 不可中断:当一个线程持有synchronized锁时,其他线程无法中断它,除非抛出异常或者正常执行结束。

2. ReentrantLock(可重入锁)

2.1 应用场景

需要更灵活的锁操作时使用,比如尝试非阻塞获取锁、可中断获取锁、公平性选择、超时获取锁。

2.2 特点

  1. 需要显示地获取和释放

  2. 可中断:当一个线程持有ReentrantLock锁时,其他线程可中断它的执行--lockInterruptibly()方法

  3. 提供了公平锁和非公平锁的选项,可以通过构造函数指定.

  4. 尝试非阻塞获取锁--tryLock()方法-线程在尝试获取锁时,如果锁不可用,线程不会进入等待状态,而是立即返回一个失败的结果.从而避免线程在等待锁的过程中被长时间阻塞,比如热点key过期,未获取锁的线程可以返回给用户历史数据,而不是阻塞在那里等待获取锁,为的就是提升用户体验.

  5. 超时获取:允许在指定时间内尝试获取锁---tryLock(long timeout, TimeUnit unit)方法--如果获取成功,则执行业务逻辑;如果超时未能获取锁,则执行其他操作或重试.

3. ReadWriteLock(读写锁)

3.1 应用场景

当读操作远多于写操作时,用于提高并发性能,允许多个读操作同时进行,写操作则独自占用锁.

3.2 特点

由两个锁组成,一个读锁.一个写锁,读锁可以被多个读操作共享,写锁是独占的.

4. OptimisticLock(乐观锁)

4.1 应用场景

一般用于读多写少的场景

4.2 特点

乐观地认为共享数据被修改的概率很低,所以在读取的时候不会加锁.一般通过版本号或者时间戳来实现.线程在提交更新的时候会检查数据是否被其他线程修改过.

5. PessimisticLock(悲观锁)

5.1 应用场景

一般用于写多读少的场景

5.2 特点

悲观地认为共享数据被修改的概率很高,因此在数据被访问的时候立即加锁,以防止其他线程的修改.

6. CountDownLatch(倒计时锁存器)

6.1 应用场景

用于一个或多个线程等待其他线程完成操作后再继续执行的场景,比如主线程阻塞,等所有子线程操作完之后,再继续执行。

6.2 特点

通过一个计数器来控制,当计数器减到0时,所有等待的线程才会继续执行.

相关推荐
石头wang几秒前
jmeter java.lang.OutOfMemoryError: Java heap space 修改内存大小,指定自己的JDK
java·开发语言·jmeter
yaoxin52112326 分钟前
292. Java Stream API - 使用构建器模式创建 Stream
java·开发语言
阮松云33 分钟前
code-server 配置maven
java·linux·maven
木木木一38 分钟前
Rust学习记录--C11 编写自动化测试
java·学习·rust
bug总结41 分钟前
uniapp+动态设置顶部导航栏使用详解
java·前端·javascript
a努力。1 小时前
字节跳动Java面试被问:一致性哈希的虚拟节点和数据迁移
java·开发语言·分布式·算法·缓存·面试·哈希算法
qq_318121591 小时前
互联网大厂Java面试故事:支付与金融服务微服务架构、消息队列与AI风控全流程解析
java·spring boot·redis·微服务·kafka·支付系统·金融服务
文慧的科技江湖1 小时前
重卡的充电桩一般都是多少千瓦? - 慧知开源充电桩平台
java·开发语言·开源·充电桩开源平台·慧知重卡开源充电桩平台
短剑重铸之日1 小时前
《7天学会Redis》Day 3 - 持久化机制深度解析
java·redis·后端·缓存
独自破碎E1 小时前
【前序+中序】重建二叉树
java·开发语言