多线程(锁策略, synchronized 对应的锁策略)

简介: 多线程(锁策略, synchronized 对应的锁策略)

锁策略

锁策略?锁机制?锁特性? 大概可以这么理解吧, 根据不同的使用场景和需求, 锁有不同的特性供实现者选择

也可以说是: 当出现锁竞争时, 不同加锁机制的特点

再或者说: 是锁的形容词

以下是几种常见的锁策略

乐观锁 vs 悲观锁

乐观锁: 预测锁的竞争不会很激烈, 因此会少做一些工作 (假设数据一般不会出现并发冲突, 因此当数据进行提交的时候, 才会对数据进行检测, 如果判断出现了并发冲突, 就返回信息给用户, 让用户决定如何去做)

乐观锁一般是基于 版本号 这样的机制来实现的, 就是该做的还是会做, 做完了会基于版本号回滚,报错 …

悲观锁: 预测锁的竞争会很激烈, 因此会多做一些工作 (每次使用数据都会上锁)

悲观锁是直接不让你用, 如果该资源已经被使用, 那么你就阻塞等待锁释放就好了

轻量级锁 vs 重量级锁

轻量级锁 加锁解锁 的开销比较小, 效率高 (多数情况下, 乐观锁也是一个轻量级锁)

重量级锁 加锁解锁 的开销比较大, 效率低 (多数情况下, 悲观锁也是一个重量级锁)

换句话说

效率高的锁就是轻量级锁

效率低的锁就是重量级锁


自旋锁 vs 挂起等待锁

自旋锁: 在产生所冲突时, 自旋锁会不断的尝试去竞争锁

挂起等待锁: 在产生冲突时, 挂起等待锁不会主动去竞争锁, 而是等锁资源被释放, 被动通知你可以来进行锁竞争


互斥锁 vs 读写锁

互斥锁: 例如 sychronized , 提供加锁和解锁两个操作, 如果一个线程加锁, 另一个线程也加锁, 就会产生阻塞

读写锁: 提供三种操作

  1. 针对读加锁
  2. 针对写加锁
  3. 解锁

读写锁中约定

  • 读锁和读锁之间没有锁冲突
  • 写锁和写锁之间锁冲突
  • 读锁和写锁之间锁冲突

公平锁 vs 非公平锁

公平锁: 当一个线程结束对某个资源的占有, 由下一个线程来获取该资源, 而下一个线程所在的就绪队列, 是有序的, 先来先到, 依次获取锁

非公平锁: 当一个线程结束对某个资源的占用, 由就绪队列中的所有线程进行抢占式获取锁, 而不是按照时间顺序, 先到先得


可重入锁 vs 不可重入锁

可重入锁: 一个线程针对一把锁, 连续加锁多次不会产生死锁

不可重入锁: 一个线程针对一把锁, 连续加锁两次就会产生死锁


以 Synchronized 为例, 对应锁策略

  1. synchronized 既是悲观锁, 也是乐观锁 (默认是乐观锁, 如果锁竞争比较激烈, 就会变成悲观锁)
  2. synchronized 既是轻量级锁, 也是重量级锁 (默认是轻量级锁, 如果锁竞争比较激烈, 就会转变成重量级锁)
  3. synchronized 的轻量级锁, 是基于自旋锁的方式实现的
    synchronized 的重量级锁, 是基于挂起等待锁实现的
  4. synchronized 是互斥锁
  5. synchronized 是非公平锁 (抢占式执行)
  6. synchronized 是可重入锁

目录
相关文章
|
24天前
|
安全 Java 编译器
线程安全问题和锁
本文详细介绍了线程的状态及其转换,包括新建、就绪、等待、超时等待、阻塞和终止状态,并通过示例说明了各状态的特点。接着,文章深入探讨了线程安全问题,分析了多线程环境下变量修改引发的数据异常,并通过使用 `synchronized` 关键字和 `volatile` 解决内存可见性问题。最后,文章讲解了锁的概念,包括同步代码块、同步方法以及 `Lock` 接口,并讨论了死锁现象及其产生的原因与解决方案。
56 10
线程安全问题和锁
|
5天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
17 2
|
2月前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
Java多线程同步大揭秘:synchronized与Lock的终极对决!
58 5
|
19天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
8天前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
15 0
|
2月前
|
监控 负载均衡 算法
线程数突增!领导说再这么写就GC掉我:深入理解与优化策略
【8月更文挑战第29天】在软件开发的世界里,性能优化总是开发者们绕不开的话题。特别是当面对“线程数突增”这样的紧急情况时,更是考验着我们的技术功底和问题解决能力。今天,我们就来深入探讨这一话题,分享一些工作学习中积累的技术干货,帮助大家避免被“GC”(垃圾回收,也常用来幽默地表示“被炒鱿鱼”)的尴尬。
37 2
|
2月前
|
Java 开发者
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选。相比 `synchronized`,Lock 提供了更灵活强大的线程同步机制,包括可中断等待、超时等待、重入锁及读写锁等高级特性,极大提升了多线程应用的性能和可靠性。通过示例对比,可以看出 Lock 接口通过 `lock()` 和 `unlock()` 明确管理锁的获取和释放,避免死锁风险,并支持公平锁选择和条件变量,使其在高并发场景下更具优势。掌握 Lock 接口将助力开发者构建更高效、可靠的多线程应用。
20 2
|
2月前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
Java多线程同步实战:从synchronized到Lock的进化之路!
86 1
|
1月前
|
安全 Java API
Java线程池原理与锁机制分析
综上所述,Java线程池和锁机制是并发编程中极其重要的两个部分。线程池主要用于管理线程的生命周期和执行并发任务,而锁机制则用于保障线程安全和防止数据的并发错误。它们深入地结合在一起,成为Java高效并发编程实践中的关键要素。
15 0
|
2月前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
64 1