多线程(锁策略, 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 是可重入锁

目录
相关文章
|
5天前
|
Java
并发编程的艺术:Java线程与锁机制探索
【6月更文挑战第21天】**并发编程的艺术:Java线程与锁机制探索** 在多核时代,掌握并发编程至关重要。本文探讨Java中线程创建(`Thread`或`Runnable`)、线程同步(`synchronized`关键字与`Lock`接口)及线程池(`ExecutorService`)的使用。同时,警惕并发问题,如死锁和饥饿,遵循最佳实践以确保应用的高效和健壮。
17 2
|
5天前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
【6月更文挑战第20天】在Java多线程编程中,`synchronized`和`Lock`是两种关键的同步机制。`synchronized`作为内置关键字提供基础同步,简单但可能不够灵活;而`Lock`接口自Java 5引入,提供更复杂的控制和优化性能的选项。在低竞争场景下,`synchronized`性能可能更好,但在高并发或需要精细控制时,`Lock`(如`ReentrantLock`)更具优势。选择哪种取决于具体需求和场景,理解两者机制至关重要。
|
5天前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
【6月更文挑战第20天】Java多线程同步始于`synchronized`关键字,保证单线程访问共享资源,但为应对复杂场景,`Lock`接口(如`ReentrantLock`)提供了更细粒度控制,包括可重入、公平性及中断等待。通过实战比较两者在高并发下的性能,了解其应用场景。不断学习如`Semaphore`等工具并实践,能提升多线程编程能力。从同步起点到专家之路,每次实战都是进步的阶梯。
|
2天前
|
Java
Java中的`synchronized`关键字是一个用于并发控制的关键字,它提供了一种简单的加锁机制来确保多线程环境下的数据一致性。
【6月更文挑战第24天】Java的`synchronized`关键字确保多线程数据一致性,通过锁定代码块或方法防止并发冲突。同步方法整个方法体为临界区,同步代码块则锁定特定对象。示例展示了如何在`Counter`类中使用`synchronized`保证原子操作和可见性,同时指出过度使用可能影响性能。
10 4
|
6天前
|
安全 Java Python
GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。
【6月更文挑战第20天】GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。线程池通过预创建线程池来管理资源,减少线程创建销毁开销,提高效率。示例展示了如何使用Python实现一个简单的线程池,用于执行多个耗时任务。
18 6
|
6天前
|
安全 Java 程序员
惊呆了!Java多线程里的“synchronized”竟然这么神奇!
【6月更文挑战第20天】Java的`synchronized`关键字是解决线程安全的关键,它确保同一时间只有一个线程访问同步代码。在案例中,`Counter`类的`increment`方法如果不加同步,可能会导致竞态条件。通过使用`synchronized`方法或语句块,可以防止这种情况,确保线程安全。虽然同步会带来性能影响,但它是构建并发应用的重要工具,平衡同步与性能是使用时需考虑的。了解并恰当使用`synchronized`,能有效应对多线程挑战。
|
6天前
|
调度
线程操作:锁、条件变量的使用
线程操作:锁、条件变量的使用
14 1
|
9天前
|
API
Linux---线程读写锁详解及代码实现
Linux---线程读写锁详解及代码实现
|
1天前
|
Java
synchronized关键字在Java中为多线程编程提供了一种简便的方式来管理并发,防止数据竞争和死锁等问题
Java的`synchronized`关键字确保多线程环境中的数据一致性,通过锁定代码段或方法防止并发冲突。它可修饰方法(整个方法为临界区)或代码块(指定对象锁)。例如,同步方法只允许一个线程执行,同步代码块则更灵活,可锁定特定对象。使用时需谨慎,以避免性能影响和死锁。
8 0
|
5天前
|
安全 Java 开发者
Java多线程同步:synchronized与Lock的“爱恨情仇”!
【6月更文挑战第20天】Java多线程中,`synchronized`和`Lock`是线程安全的保障。`synchronized`简单易用,但有局限,如不可中断、无公平策略。`Lock`接口及`ReentrantLock`提供更细粒度控制,支持可中断、公平锁和条件变量,适合复杂场景。在选择时,应根据项目需求权衡简易性和灵活性。示例展示了两者用法差异,强调正确管理锁以避免死锁。理解特点,灵活应用,是多线程编程的关键。