排他锁

简介: 排他锁(写锁)是一种互斥机制,确保同一时间仅一个线程访问共享资源,保障数据一致性与完整性。适用于写操作场景,如更新、删除等,常见于数据库和多线程编程。其优点为强一致性和实现简单,但并发度低且存在死锁风险。可通过synchronized、ReentrantLock等方式实现。

排他锁(Exclusive Lock),也称为写锁互斥锁,是一种严格的并发控制机制,确保同一时间只有一个线程能够访问和修改共享资源。其他线程在锁被释放前,无法进行读或写操作,从而保证数据的一致性和完整性。

核心原理

  1. 独占访问

    • 线程获取排他锁后,独占资源,禁止其他线程的读写请求。
    • 适用于写操作,如数据更新、删除等场景。
  2. 锁的互斥性

    • 排他锁与任何其他锁(包括共享锁、其他排他锁)互斥。
    • 必须等待当前锁释放后,其他线程才能获取锁。

排他锁的优缺点

  • 优点

    • 强一致性:确保数据修改的原子性,避免脏写和数据竞争。
    • 实现简单:多数编程语言和数据库提供内置支持。
  • 缺点

    • 并发度低:同一时间仅一个线程可操作,可能导致性能瓶颈。
    • 死锁风险:多线程循环等待锁时可能产生死锁。

实现方式

1. 数据库层面

  • MySQL
    SELECT * FROM table WHERE id = ? FOR UPDATE; -- 排他锁
    
    • 事务提交前,其他事务无法读取或修改该行数据。

2. Java语言实现

  • synchronized关键字

    public class SynchronizedExample {
         
        private final Object lock = new Object();
    
        public void writeData() {
         
            synchronized (lock) {
         
                // 临界区代码,同一时间仅一个线程执行
            }
        }
    }
    
  • ReentrantLock

    import java.util.concurrent.locks.ReentrantLock;
    
    public class ReentrantLockExample {
         
        private final ReentrantLock lock = new ReentrantLock();
    
        public void writeData() {
         
            lock.lock();
            try {
         
                // 临界区代码
            } finally {
         
                lock.unlock(); // 必须在finally中释放锁
            }
        }
    }
    
  • ReadWriteLock的写锁

    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    public class WriteLockExample {
         
        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    
        public void writeData() {
         
            rwLock.writeLock().lock(); // 获取写锁(排他锁)
            try {
         
                // 写操作,禁止其他线程读写
            } finally {
         
                rwLock.writeLock().unlock();
            }
        }
    }
    

排他锁的典型应用场景

  1. 数据更新操作

    • 如库存扣减、账户转账,确保原子性。
  2. 文件写入

    • 避免多线程同时修改文件导致数据错乱。
  3. 临界资源访问

    • 如全局计数器、配置文件修改。

与其他锁的对比

锁类型 读并发 写并发 互斥对象 适用场景
排他锁 独占 独占 读锁、写锁 写操作为主,如账户扣款
共享锁 允许多个 独占 写锁 读多写少,如数据库查询
乐观锁 无锁 CAS检查 无(冲突重试) 冲突少的读多写少场景
悲观锁 独占 独占 所有操作 冲突多的写操作场景

注意事项

  1. 死锁预防

    • 按相同顺序获取锁,设置锁超时时间。
    • 使用ReentrantLock.tryLock()避免死锁。
  2. 锁粒度优化

    • 避免在大方法上加锁,减小锁的范围。
  3. 性能监控

    • 高并发场景下,通过工具(如JStack)监控锁竞争情况。

Java中的排他锁工具

  1. synchronized关键字

    • 隐式锁,由JVM自动释放。
  2. ReentrantLock

    • 显式锁,支持公平锁、可中断锁、条件变量。
  3. ReadWriteLock的写锁

    • 与读锁配合使用,实现读写分离。

总结

排他锁通过独占资源确保数据一致性,适用于写操作频繁、对数据完整性要求高的场景。但在高并发环境下,过度使用会导致性能瓶颈。现代系统通常结合排他锁与其他锁机制(如共享锁、乐观锁),根据业务特点选择合适的并发控制策略,以平衡性能与数据安全。

目录
相关文章
|
2月前
|
存储 Java 对象存储
轻量级锁
轻量级锁是JVM为提升多线程性能而引入的锁机制,通过CAS操作减少线程阻塞,适用于同步块执行时间短且线程竞争不激烈的场景。其核心在于使用栈帧中的锁记录与CAS操作实现高效加锁,避免用户态与内核态切换带来的性能损耗。当无竞争时,仅需一次CAS即可完成锁获取;若竞争激烈,则可能升级为重量级锁。相比偏向锁和重量级锁,轻量级锁在低竞争环境下具有更高的效率。
77 0
|
2月前
|
Java Spring
聊聊你对SpringBoot框架的理解 ?
SpringBoot是Spring家族中流行的子项目,旨在简化Spring框架开发的繁琐配置。它主要提供三大功能:starter起步依赖简化依赖管理,自动配置根据条件创建Bean,以及内嵌Web服务器支持Jar包运行,极大提升了开发效率。
125 0
|
2月前
|
缓存 Java
对比 synchronized 和 volatile
`synchronized` 和 `volatile` 是 Java 并发编程中的两个关键机制,各有侧重。`synchronized` 用于实现线程的互斥访问,保证原子性、可见性和有序性,适用于需要锁的场景;而 `volatile` 更轻量,仅确保变量的可见性和有序性,适用于状态标志等无需复合操作的场景。两者可互补使用,如双重检查单例中结合二者优势。合理选择有助于提升并发性能与代码安全性。
120 0
|
2月前
|
存储 安全 Java
synchronized 锁升级
JDK 6 引入的 synchronized 锁升级机制,通过偏向锁、轻量级锁和重量级锁的动态切换,优化了多线程同步性能。该机制根据竞争情况逐步升级锁状态,减少线程阻塞和系统调用开销,从而提升并发效率。
123 0
|
2月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 > Java系统属性 > application.properties > application.yml > application.yaml。
528 0
|
2月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
729 0
|
2月前
|
缓存 Java 关系型数据库
共享锁
共享锁允许多个线程同时读取共享资源,写操作时阻塞其他线程,通过“读共享、写独占”策略提升并发性能,适用于读多写少场景,如缓存、数据库查询等。
77 0
|
2月前
|
存储 Java 容器
偏向锁
偏向锁是JVM为提升单线程环境下锁性能而引入的优化机制。其核心思想是将锁偏向首个获取它的线程,避免无竞争时的同步开销,从而提高执行效率。适用于锁由同一线程多次获取、无并发竞争的场景。一旦出现多线程竞争,偏向锁会撤销并升级为更高级别的锁。合理使用可显著提升性能,但在高并发环境下需谨慎配置。
46 0
|
2月前
|
Java Maven 开发工具
SpringBoot使用汇总
本节介绍 Spring Boot 工程的构建方法,包括使用 IDEA 快速创建项目、通过官方平台生成项目、配置 Maven 以及设置编码格式等内容。涵盖 Group 和 Artifact 的填写规范、依赖添加、IDE 配置与推荐设置,助力快速搭建开发环境。
117 3
|
2月前
|
Java 应用服务中间件 Maven
SpringBoot使用汇总
本节介绍了Spring Boot项目工程结构,包含src/main/java(业务代码)、src/main/resources(静态与配置文件)和src/test/java(测试代码)。通过@SpringBootApplication注解的启动类运行main方法即可快速启动应用。Spring Boot内置Tomcat,简化配置流程。示例展示了创建Controller、访问接口及修改默认端口的方法,帮助开发者快速上手Spring Boot开发。
100 2

热门文章

最新文章