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

Java锁

在 Java 中,锁(Lock)是用于控制多线程对共享资源访问的机制,确保线程安全。Java 提供了多种锁机制,主要包括以下几种:


1. synchronized 关键字

synchronized 是 Java 中最基本的锁机制,可以用于方法或代码块。

用法
  • 修饰实例方法:锁住当前对象实例。

    public synchronized void method() {
        // 线程安全的代码
    }
  • 修饰静态方法:锁住当前类的 Class 对象。

    public static synchronized void staticMethod() {
        // 线程安全的代码
    }
  • 修饰代码块:锁住指定对象。

    public void method() {
        synchronized (this) { // 锁住当前对象
            // 线程安全的代码
        }
    }
特点
  • 简单易用,无需手动释放锁。

  • 不支持超时、中断等高级功能。

  • 性能较低,适合简单的同步场景。


2. ReentrantLock

ReentrantLock 是 java.util.concurrent.locks 包中的锁实现,提供了比 synchronized 更强大的功能。

用法
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Example {
    private final Lock lock = new ReentrantLock();

    public void method() {
        lock.lock(); // 加锁
        try {
            // 线程安全的代码
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}
特点
  • 支持可重入(同一个线程可以多次获取锁)。

  • 支持公平锁和非公平锁(默认是非公平锁)。

  • 支持超时获取锁、可中断获取锁等高级功能。

    if (lock.tryLock(1, TimeUnit.SECONDS)) { // 尝试获取锁,最多等待 1 秒
        try {
            // 线程安全的代码
        } finally {
            lock.unlock();
        }
    } else {
        // 未获取到锁的处理逻辑
    }

3. ReadWriteLock

ReadWriteLock 是一种读写锁,允许多个读线程同时访问,但写线程独占访问。

用法
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Example {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void readMethod() {
        rwLock.readLock().lock(); // 加读锁
        try {
            // 读操作
        } finally {
            rwLock.readLock().unlock(); // 释放读锁
        }
    }

    public void writeMethod() {
        rwLock.writeLock().lock(); // 加写锁
        try {
            // 写操作
        } finally {
            rwLock.writeLock().unlock(); // 释放写锁
        }
    }
}
特点
  • 读写分离,提高并发性能。

  • 写锁是独占锁,读锁是共享锁。


4. StampedLock

StampedLock 是 Java 8 引入的一种更高效的读写锁,支持乐观读锁。

用法
import java.util.concurrent.locks.StampedLock;

public class Example {
    private final StampedLock stampedLock = new StampedLock();

    public void readMethod() {
        long stamp = stampedLock.tryOptimisticRead(); // 尝试乐观读
        // 读操作
        if (!stampedLock.validate(stamp)) { // 检查是否被写操作修改
            stamp = stampedLock.readLock(); // 获取悲观读锁
            try {
                // 读操作
            } finally {
                stampedLock.unlockRead(stamp); // 释放读锁
            }
        }
    }

    public void writeMethod() {
        long stamp = stampedLock.writeLock(); // 获取写锁
        try {
            // 写操作
        } finally {
            stampedLock.unlockWrite(stamp); // 释放写锁
        }
    }
}
特点
  • 支持乐观读锁,减少锁竞争。

  • 比 ReadWriteLock 性能更高,但使用更复杂。


5. 其他锁

  • Condition:与 ReentrantLock 配合使用,实现线程间的等待/通知机制。

    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    
    lock.lock();
    try {
        condition.await(); // 等待
        condition.signal(); // 唤醒
    } finally {
        lock.unlock();
    }
  • Semaphore:信号量,用于控制同时访问资源的线程数量。

    Semaphore semaphore = new Semaphore(10); // 允许 10 个线程同时访问
    semaphore.acquire(); // 获取许可
    try {
        // 访问资源
    } finally {
        semaphore.release(); // 释放许可
    }
  • CountDownLatch:倒计时锁,用于等待多个线程完成任务。

    CountDownLatch latch = new CountDownLatch(3); // 需要等待 3 个线程
    latch.await(); // 等待
    latch.countDown(); // 完成任务
  • CyclicBarrier:循环屏障,用于多个线程相互等待。

    CyclicBarrier barrier = new CyclicBarrier(3); // 3 个线程相互等待
    barrier.await(); // 等待其他线程

总结

锁机制特点
synchronized简单易用,性能较低,适合简单场景。
ReentrantLock功能强大,支持可重入、公平锁、超时、中断等。
ReadWriteLock读写分离,提高并发性能。
StampedLock高性能读写锁,支持乐观读锁。
Condition与 ReentrantLock 配合使用,实现线程间通信。
Semaphore控制同时访问资源的线程数量。
CountDownLatch等待多个线程完成任务。
CyclicBarrier多个线程相互等待。

根据具体需求选择合适的锁机制。对于高并发场景,推荐使用 ReentrantLock 或 StampedLock

相关文章:

  • AF3 curry1函数解读
  • 洛谷P1102 A-B 数对
  • 计算机组成原理---操作系统Linux
  • Mybatis 的关联映射(一对一,一对多,多对多)
  • 是德科技十周年:以创新丈量未来,用科技赋能世界
  • springboot项目使用中创InforSuiteAS替换tomcat
  • makefile新手入门教程
  • 【内网服务发布公网】
  • 《水利水电安全员考试各题型对比分析及应对攻略》
  • nftables 入门:简洁高效的 Linux 防火墙管理
  • 基于大型模实现的AiEditor
  • 数据结构与算法 计算机组成 八股
  • Aws batch task 无法拉取ECR 镜像unable to pull secrets or registry auth 问题排查
  • GPU的架构原理解析
  • 蓝桥杯备考:动态规划路径类DP之矩阵的最小路径和
  • 【Altium】22.11版本后如何导出Gerber镜像层
  • aardio - 虚表 + 数据库 操作例程
  • 《Operating System Concepts》阅读笔记:p200-p202
  • 高效处理 List<T> 集合:更新、查找与优化技巧
  • C++ 中 `shared_ptr` 的用法及常见陷阱解析
  • 住建部:2019年至2024年,全国累计开工改造老旧小区28万个
  • 新华每日电讯:把纪律的螺丝拧得紧而又紧
  • 新疆巴音郭楞州和硕县发生4.6级地震,震源深度10千米
  • 前4个月全国新建商品房销售面积降幅收窄,房地产库存和新开工有所改善
  • AI创业者聊大模型应用趋势:可用性和用户需求是关键
  • 打造信息消费新场景、新体验,上海信息消费节开幕