首页 > Java > java教程 > java中Lock API概述

java中Lock API概述

Linda Hamilton
发布: 2024-12-31 18:59:14
原创
480 人浏览过

Overview of Lock API in java

管理对共享资源的访问对于并发编程中确保数据一致性非常重要。传统的synchronized关键字对于公平性、立即获取锁、等待特定时间获取锁等复杂场景缺乏灵活性。Java 1.5中引入了Lock、ReadWriteLock和StampedLock API来解决这些限制,并为开发人员提供了很好的控制来处理共享资源访问。它们是 java.util.concurrent 包的一部分。

锁定API

Lock API 是一个接口,提供以下方法来处理线程同步。

  • void lock() 用于获取锁。如果锁不可用,线程将被阻塞,直到获取锁。
  • void lockInterruptically() 与lock()相同,但该线程可以被中断。
  • boolean tryLock() 如果获得锁则返回true;否则为假。如果没有授予锁,线程不会被阻塞。
  • boolean tryLock(long timeout, TimeUnit unit) 与 tryLock() 相同,但仅等待指定的时间。
  • voidunlock()释放锁。
  • Condition newCondition() 为线程提供在执行关键部分时等待某些条件发生的能力。

可重入锁

  • ReentrantLock 类实现了 Lock 接口。 
  • 可重入锁允许线程多次获取锁并多次释放它。
  • 如果你想要公平策略,请使用 ReentrantLock 的参数化构造函数。
  • 如果启用公平性,它会确保等待时间最长的线程能够访问锁。
  • 使用finally块释放锁以避免死锁情况。
ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}
登录后复制
登录后复制

读写锁API

ReadWriteLock API 是一个接口,维护一对锁来维护读写场景。如果没有写入者,读锁可以由多个线程同时持有。写锁是独占的。

  • Lock readLock() - 返回用于读取的锁。
  • Lock writeLock() - 返回用于写入的锁。

关键规则

  • 如果有读锁,则无法获取写锁。
  • 如果拥有写锁,则无法在任何其他线程中获取读锁。
  • 如果你有一个写锁,你可以在同一个线程中获取另一个写锁。
  • 当没有其他读或写锁处于活动状态时,允许写锁。
  • 等待写锁时,不允许来自其他线程的新读锁。

可重入读写锁

  • ReentrantReadWriteLock 类实现了 ReadWriteLock 接口。
  • 如果我们有更多的阅读量而不是写入量,那么很有用。

示例:在微服务通信中,假设服务 B 需要来自服务 A 的 JWT。JWT 由服务 A 生成,并且可以缓存几分钟。在这种情况下ReentrantReadWriteLock会更有用。如果令牌过期或即将过期,我们可以更新令牌。我在这里不获取读锁以避免读饥饿。

ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}
登录后复制
登录后复制

印记锁API

StampedLock 是在 Java 8 中引入的,它是一个类。它支持三种锁定模式并返回用于释放锁定的标记。它允许锁升级。

  1. 读锁允许多个线程并发读取。
  2. Write Lock 返回用于写入的锁。
  3. 乐观读锁允许线程在不获取传统读锁的情况下进行读取,从而避免争用,从而提高性能。
  • long writeLock() 获取独占锁,必要时阻塞直至可用。
  • void unlockWrite(long stamp) 释放写锁。
  • long readLock() 获取读锁,如果正在进行写锁则阻塞。
  • void unlockRead(long stamp) 释放读锁。
  • long tryOptimisticRead() 返回一个稍后可以验证的标记,如果独占锁定则返回零。
  • boolean validate(long stamp) 如果自给定戳记发布以来尚未独占获取锁(写锁),则返回 true;否则,错误。
  • long tryConvertToWriteLock(long stamp) 将读锁或乐观锁升级为写锁。阻塞直到可用。

要点:

  • 它是不可重入,这意味着持有锁的线程无法再次获取它。
  • 不支持条件。
  • 它不支持公平。
String jwt = JwtUtil.generateJwt();
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock writeLock = lock.writeLock();
Lock readLock = lock.readLock();

public String getJwt(String key, String value) {
    if (StringUtils.hasLength(jwt)) {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            generateJwt();
        }
    } else {
        generateJwt();
    }
    return this.jwt;
}

public void generateJwt() {
    this.writeLock.lock(); //write lock
    try {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            this.jwt = JwtUtil.generateJwt();
        }
    } finally {
        this.writeLock.unlock(); //release write lock
    }
}
登录后复制

乐观的阅读示例。这允许线程在不获取传统读锁的情况下进行读取,从而避免了锁争用,从而提高了性能。如果在获取乐观读锁时间后获取了任何写锁,validate() 将返回 false,否则返回 true。

public void readAndWrite() {
    long l = this.stampedLock.readLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(l);
    }

    long w = this.stampedLock.writeLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(w);
    }
}
登录后复制

快乐编码和学习!!!

如有任何问题请留言。

以上是java中Lock API概述的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板