可重入锁 ReentrantLock 使用

320次阅读
5条评论

共计 1631 个字符,预计需要花费 5 分钟才能阅读完成。

ReentrantLock可重入锁)是 Java 中的一种同步机制,它提供了与synchronized关键字相似的功能,但具有更灵活的特性。在多线程编程中,ReentrantLock允许线程在获取锁之后再次获取同一把锁,而不会导致死锁。

ReentrantLock 具有以下特点:

  1. 可重入性:

ReentrantLock是可重入的,这意味着一个线程可以多次获取同一把锁而不会产生死锁。当线程重复获取锁时,它必须相应地释放同样次数的锁,才能完全释放锁资源。

  1. 互斥性:

ReentrantLock保证了线程对共享资源的互斥访问。一次只有一个线程可以持有这把锁,其他线程必须等待锁释放才能获得锁。

  1. 等待可中断:

通过lockInterruptibly()方法,线程可以在等待锁的过程中被中断,而不是一直阻塞等待。这种特性能够避免线程长时间阻塞,提高系统的响应性。

  1. 公平性:

ReentrantLock可以在创建时选择是否公平锁。公平锁是指锁的获取按照请求的顺序进行,而非公平锁则允许插队。公平锁会导致线程切换的开销增加,但能避免饥饿问题。

Sychronized 和 ReentrantLock 比较:

synchronized ReentrantLock
Java中的一个关键字 JDK提供的一个类
JVM层面的锁 API层面的锁
自动加锁与释放锁 需要手动加锁与释放锁
不可获取当前线程是否上锁 可获取当前线程是否上锁isHeldByCurrentThread
非公平锁 公平锁或非公平锁
不可中断 可中断 1:调用设置超时方法tryLock(long timeout ,timeUnit unit) 2:调用lockInterruptibly()放到代码块中,然后调用interrupt()方法可以中断
锁的是对象,锁信息保存在对象头中 int类型的state标识来标识锁的状态
底层有锁升级过程 没有锁升级过程

简单实用案例:

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

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

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }

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

        // 创建并启动两个线程,分别增加计数器的值
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        thread1.start();
        thread2.start();

        // 等待两个线程执行完毕
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出最终的计数器值
        System.out.println("Final Count: " + example.getCount());
    }
}

需要注意的是,使用ReentrantLock时,一定要确保在合适的位置释放锁,通常在finally块中释放锁以确保不管是否发生异常都能释放锁资源,避免死锁情况。

提醒:本文发布于136天前,文中所关联的信息可能已发生改变,请知悉!

AD:【腾讯云服务器大降价】2核4G 222元/3年 1核2G 38元/年
正文完
 
阿蛮君
版权声明:本站原创文章,由 阿蛮君 2024-04-24发表,共计1631字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(5条评论)
nnn 评论达人 LV.1
2024-04-28 12:32:05 回复

什么,还有人在入我大清

 Windows  Edge  中国广东省深圳市移动
    阿蛮君 博主
    2024-04-28 12:33:06 回复

    @nnn 

     Windows  Edge  中国广东省广州市电信
      nnn 评论达人 LV.1
      2024-04-28 12:34:43 回复

      @阿蛮君 还有,评论区里面填写昵称,有问题,不可以用中文作为昵称

       Windows  Edge  中国广东省深圳市移动
        阿蛮君 博主
        2024-04-28 12:35:59 回复

        @nnn 居然这么多人想用中文名,那我去掉限制吧

         Windows  Edge  中国广东省广州市电信
          john 评论达人 LV.1
          2024-05-01 23:37:53 回复

          @阿蛮君 中文多好呀

           Windows  Chrome  中国湖南省郴州市电信
Copyright © 2022-2024 阿蛮君博客 湘ICP备2023001393号
本网站由 亿信互联 提供云计算服务 | 蓝易云CDN 提供安全防护和加速服务
Powered by Wordpress  Theme by Puock