synchronized和ReentrantLock之间的区别

2023-05-16

synchronized和ReentrantLock的区别

  1. synchronized是一个关键字,是JVM内部实现的;ReentrantLock是标准库的一个类,是JVM外部基于Java实现的。
  2. synchronized在申请锁失败时会死等;ReentrantLock可以通过tryLock的方式等待一段时间就放弃。
  3. synchronized使用时不需要手动释放锁;ReentrantLock使用时需要手动释放锁,它更加灵活,但是容易忘记unlock
  4. synchronized是一个非公平锁;ReentrantLock默认是非公平锁,但它可以通过在构造方法中传入一个true开启公平锁模式。

在这里插入图片描述

  1. ReentrantLock的唤醒机制比synchronized更加强大,synchronized是通过Object类的wait/notify实现等待-唤醒,且每次唤醒的是一个随机等待的线程;ReentrantLock搭配Condition类实现等待-唤醒,可以更加精确的控制唤醒某个指定的线程。

三个线程交替打印ABC案例(ReentrantLock搭配Condition展现的指定唤醒功能):
在这里插入图片描述

//交替打印ABC ReentrantLock

/**
 *  loker.lock()放在try的第一行或者try的外面!!!
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Demo_4 {

    static ReentrantLock loker = new ReentrantLock();

    static Condition A = loker.newCondition();
    static Condition B = loker.newCondition();
    static Condition C = loker.newCondition();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                loker.lock();
                for (int i = 0; i < 10; i++) {
                    A.await();//等待其他线程唤醒
                    B.signal();//唤醒线程
                    System.out.println("A");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                loker.unlock();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                loker.lock();
                for (int i = 0; i < 10; i++) {
                    B.await();//等待其他线程唤醒
                    C.signal();//唤醒线程
                    System.out.println("B");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                loker.unlock();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                loker.lock();
                for (int i = 0; i < 10; i++) {
                    C.await();//等待其他线程唤醒
                    A.signal();//唤醒线程
                    System.out.println("C");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                loker.unlock();
            }
        });
        //上面线程循环
        t1.start();
        t2.start();
        t3.start();

        Thread.sleep(1000);//确保线程都启动

        //从A切入启动线程
        try {
            loker.lock();
            A.signal();
        } finally {
            loker.unlock();
        }
    }
}
  1. synchronized是基于操作系统的mutex锁实现的;ReentrantLock是基于CAS和AQS实现的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

synchronized和ReentrantLock之间的区别 的相关文章

  • 详解Java锁对象

    1 Synchronized 1 1 synchronized特性 1 互斥 synchronized会起到互斥效果 某个线程执行到某个对象的synchronized中时 其他线程如果也执行到同一个对象synchronized就会阻塞等待
  • Java线程学习实例——采用同步锁,互斥锁与同步锁的区别,synchronized的使用方法

    栗子来源 https blog csdn net wenzhi20102321 article details 52524545 首先对java中同步锁与互斥锁进行区分 主要来源于知乎中的大佬总结如下 1 锁的概念 锁的目的就是避免多个线程
  • java.concurrent.ReentrantLock - 为什么我们要多次获取相同的锁[重复]

    这个问题在这里已经有答案了 我知道如果使用 ReentrantLock 它允许同一线程多次获取同一锁 其内部有一个计数器来统计获取锁的次数 如果您两次获取同一个锁 则需要释放它两次 但我的问题是 为什么有人想要多次获取锁 一次获取就足够了吗
  • java中的final变量和synchronized块

    Java中的final变量是什么 例如 如果我写final int temp 函数中final关键字的含义是什么 另外 我什么时候想使用final变量 既作为类变量又作为函数变量 为什么同步块中的变量必须声明为final Final 变量和
  • Java:如何检查是否可以获得锁? [复制]

    这个问题在这里已经有答案了 如果我想确保对 Java 中的对象进行独占访问 我可以这样写 Zoo zoo findZoo synchronized zoo zoo feedAllTheAnimals 有没有办法检查对象当前是否被锁定 如果另
  • 我应该使用同步方法来改变该字段吗?

    随着接下来的课程 This class should be thread safe class BankAccount private long balance Should it be volatile synchronized void
  • 通过此与虚拟对象同步

    到目前为止 我已经看到了同步块的用法 但最近我了解到使用虚拟对象更好 我发现以下与此相关的主题 Java同步方法锁定对象或方法 总而言之 在下面的代码中 两个不同的对象不能同时运行 addA 和 addB 因为它们都使用 this 作为锁
  • 为什么同步字段变量并在同步块内递增它会导致打印乱序?

    我有一个简单的代码片段 public class ItemManager private Integer itemCount 0 public void incrementAndPrint synchronized this System
  • 有一个专用的锁对象有用吗? [复制]

    这个问题在这里已经有答案了 我正在清理遗留的java代码 我发现了以下构造 final class QuiteComplexClass private Object lock new Object void aMethod synchron
  • 如何检查对象是否正在@synchronized

    有时我会编写以下代码来同步例程 synchronized objToBeSync 当两个线程尝试同时访问同步块时 其中一个线程会阻塞其他线程 直到其中一个线程退出同步块 但是 有时我不希望一个对象阻塞另一个对象 但其他对象检查对象是否正在同
  • Java中有同步队列吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 有同步的吗QueueJava 中的类
  • 学习Java,synchronized关键字的使用

    所以我正在测试synchronized关键词 这是我尝试过的一个例子 public class MyTest static int i 0 public static void main String args new Thread t1
  • FileReader API:如何同步读取文件

    我正在尝试读取使用 html 页面上的输入类型文件选择的文件 我已经实现了读取文件的功能 并且可以读取文件内容 但实际问题是正在读取文件内容异步地它允许执行脚本的其他功能 我将读取的文件内容存储在数组中 当移动到其他函数时 数组是空的 当引
  • 如果一个同步方法调用另一个非同步方法,该非同步方法是否有锁

    在Java中 如果一个同步方法包含对非同步方法的调用 那么另一个方法是否仍然可以同时访问该非同步方法 基本上我要问的是同步方法中的所有内容都有锁 包括对其他同步方法的调用 如果一个同步方法调用另一个非同步方法 该非同步方法是否有锁 答案取决
  • Java中的多个对象锁?

    锁定私有字段变量 而不是使用锁定对象 是否安全 可接受的做法 这样 我就可以为不同的目的使用不同的锁 下面的例子 class Test private Integer x 0 private Integer y 0 public void
  • Java并发中的AbstractQueuedSynchronizer

    What is AbstractQueuedSynchronizer在Java中concurrent locks包用来做什么 有人可以阐明它的方法吗doAcquireInterruptibly and parkAndCheckInterru
  • 分布式张量流 tf.train.SyncReplicasOptimizer 似乎不同步

    我使用两个工作程序 副本和一个参数服务器 喜欢 ps hosts hosta com 2222 worker hosts hosta com 2223 hostb com 2223 使用tf train SyncReplicasOptimi
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • 在java中以原子方式获取多个锁

    我有以下代码 注意 为了可读性 我尽可能简化了代码 如果我忘记了任何关键部分 请告诉我 public class User private Relations relations public User relations new Rela
  • Java基于参数的同步(名为互斥锁/锁)

    我正在寻找一种根据接收到的参数来同步方法的方法 如下所示 public synchronized void doSomething name some code 我想要方法doSomething同步基于name参数如下 线程 1 doSom

随机推荐