当前位置: 首页 > article >正文

问:聊聊JAVA中的共享锁和独占锁?

在Java并发包java.util.concurrent中,ReentrantLock是独占锁的一个典型实现,而ReentrantReadWriteLock则提供了共享锁和独占锁的实现。本文将介绍一下这两种锁。

独占锁(Exclusive Lock)

独占锁模式下,每次只能有一个线程持有锁。这意味着当一个线程持有锁时,其他线程必须等待该线程释放锁后才能获取锁。ReentrantLock就是以独占方式实现的互斥锁。

代码示例

import java.util.concurrent.locks.ReentrantLock;

public class ExclusiveLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();  // 获取独占锁
        try {
            count++;
        } finally {
            lock.unlock();  // 释放独占锁
        }
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        ExclusiveLockExample example = new ExclusiveLockExample();
        
        // 创建多个线程同时执行increment操作
        for (int i = 0; i < 10; i++) {
            new Thread(example::increment).start();
        }
        
        // 等待所有线程执行完毕
        // (实际应用中可使用更合适的同步机制,如CountDownLatch)
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Final count: " + example.getCount());
    }
}

在上面的代码中,increment方法使用ReentrantLock来确保在同一时间只有一个线程能够修改count变量。

共享锁(Shared Lock)

共享锁允许多个线程同时获取锁,并发访问共享资源。ReentrantReadWriteLock中的读锁(ReadLock)就是共享锁的一个实现。

代码示例

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SharedLockExample {
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
    private int count = 0;

    public void readCount() {
        readLock.lock();  // 获取共享锁
        try {
            System.out.println("Read count: " + count);
        } finally {
            readLock.unlock();  // 释放共享锁
        }
    }

    public void writeCount(int newValue) {
        writeLock.lock();  // 获取独占锁
        try {
            count = newValue;
        } finally {
            writeLock.unlock();  // 释放独占锁
        }
    }

    public static void main(String[] args) {
        SharedLockExample example = new SharedLockExample();

        // 创建多个读线程
        for (int i = 0; i < 5; i++) {
            new Thread(example::readCount).start();
        }

        // 创建一个写线程
        new Thread(() -> example.writeCount(42)).start();
        
        // 等待所有线程执行完毕
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码中,readCount方法使用读锁(共享锁)来允许多个线程同时读取count变量,而writeCount方法使用写锁(独占锁)来确保在写操作期间没有其他线程读取或写入count变量。

总结

特性独占锁 (ReentrantLock)共享锁 (ReentrantReadWriteLock.ReadLock)
锁类型互斥锁,每次只能有一个线程持有允许多个线程同时持有
并发性低,因为只有一个线程能访问资源高,因为多个读线程能同时访问资源
使用场景需要确保数据一致性的写操作允许多个读操作并发执行,但写操作需要独占
JAVA类ReentrantLockReentrantReadWriteLock.ReadLock
锁获取lock() 方法readLock().lock() 方法
锁释放unlock() 方法readLock().unlock() 方法

独占锁和共享锁在Java并发编程中各有其适用场景。独占锁适用于需要严格保证数据一致性的写操作,而共享锁则适用于允许多个读操作并发执行的场景。在实际应用中,应根据具体需求选择合适的锁类型。


http://www.kler.cn/news/321449.html

相关文章:

  • 了解针对基座大语言模型(类似 ChatGPT 的架构,Decoder-only)的重头预训练和微调训练
  • 前端Vue 基础学习1
  • 暗黑破坏神4新资料片憎恶之躯即将上线,第六赛季暗黑破坏神4搬砖如何获得最大收益?
  • 响应式的几种解决方案——媒体查询、flex、grid、多列布局、瀑布流和数据可视化屏幕的缩放处理
  • 极狐GitLab 17.4 重点功能解读【三】
  • crontab -e 修改为vim 编辑
  • Jenkins 2.477版本升级
  • 嵌入式学习——进程间通信方式(1)——有名管道和匿名管道
  • 高频 SQL 50 题(基础版)| 180. 连续出现的数字
  • The Open Group 2024生态系统架构·可持续发展年度大会全面解读
  • 企业微信AI社群助手:赋能企业私域运营的新引擎
  • JAVA集成Jasypt进行加密、解密(SpringBoot)
  • 【ARM 嵌入式 编译系列 10.4 -- GNU Binary Utilies】
  • python测试开发---前后端交互Axios
  • 利用 ARMxy边缘计算网关和 BLiotlink 软网关,实现工业智能化升级
  • VB.NET中如何利用ADO.NET Entity Framework进行ORM(对象关系映射)
  • 在Mac电脑上安装adb环境
  • npm 安装newman时idealTree:vue: sill idealTree buildDeps卡住了(实测成功)
  • 初识C语言(三)
  • VC++同时处理ANSI和Unicode字符集,除了使用TCHAR和_T()宏外,还有其他方法可以实现吗?
  • 【含文档】基于Springboot+微信小程序 的高校社团管理小程序(含源码+数据库+lw)
  • fastdfs开源分布式文件系统及迁移部署
  • mvnd 初体验
  • 探索5 大 Node.js 功能
  • 【递归】7. leetcode 404 左叶子之和
  • 宠物浮毛难清理,希喂、小米、美的宠物空气净化器该选哪款?
  • 深度学习:自然语言处理的基本原理
  • sqlserver迁移数据库文件存储位置
  • Java2 实用教程(第6版)习题2 第四题
  • Python | Leetcode Python题解之第438题找到字符串中所有字母异位词