Lock锁的使用

一、Lock锁概述

在Java 5之后,引入了一个新的并发API,位java.util.concurrent.locks包下,提供了比synchronized关键字更灵活的锁定机制。Lock接口是其中的核心,它提供了比synchronized更丰富的功能,比如尝试非阻塞地获取锁、能被中断的锁获取以及尝试获取锁时提供超时等。

二、Lock锁的使用

以下是使用ReentrantLock(实现了Lock接口的一个具体实现)的代码例子及注释:

java 复制代码
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class CounterWithLock {
    // 共享资源:计数器
    private int count = 0;
    // 创建一个ReentrantLock实例
    private final Lock lock = new ReentrantLock();
    // 使用Lock增加计数器
    public void increment() {
        // 获取锁
        lock.lock();
        try {
            count++; // 访问共享资源
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
    // 使用Lock减少计数器
    public void decrement() {
        // 获取锁
        lock.lock();
        try {
            count--; // 访问共享资源
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
    // 获取当前计数器的值
    public int getCount() {
        return count;
    }
    public static void main(String[] args) {
        CounterWithLock counter = new CounterWithLock();
        // 创建线程1,执行增加操作
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        // 创建线程2,执行减少操作
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.decrement();
            }
        });
        // 启动线程1和线程2
        t1.start();
        t2.start();
        // 等待线程1和线程2执行完毕
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 输出最终计数器的值
        System.out.println("Final count: " + counter.getCount());
    }
}

代码解释:

  1. 定义了一个名为CounterWithLock的类,其中包含一个共享资源count和一个ReentrantLock实例。

  2. increment()decrement()方法用于增加和减少计数器。这两个方法中,通过调用lock.lock()获取锁,然后执行操作,最后在finally块中调用lock.unlock()释放锁。这样可以确保即使发生异常,锁也能被正确释放。

  3. main()方法中,创建了两个线程t1t2,分别执行增加和减少操作。

  4. 通过调用t1.start()t2.start()启动线程1和线程2。

  5. 使用t1.join()t2.join()等待线程1和线程2执行完毕。

  6. 输出最终计数器的值。 通过上述代码,我们可以看到,使用Lock锁可以保证在多线程环境下共享资源count的正确性。与synchronized相比,Lock提供了更灵活的锁定操作,比如可以尝试获取锁而不立即阻塞,或者可以响应中断。 请注意,虽然Lock提供了更多的灵活性,但也需要更谨慎地使用。例如,在finally块中释放锁是一个很好的实践,以避免死锁的发生。此外,使用Lock时,获取锁和释放锁的操作必须成对出现,否则可能导致资源泄露或其他线程无法获取锁。

相关推荐
白露与泡影21 小时前
从 JDK 8 到 JDK 18,Java 垃圾回收的十次进化
java·开发语言·测试工具
一晌小贪欢21 小时前
Streamlit应用如何部署到 Streamlit Community Cloud(保姆级教程)
开发语言·阿里云·部署·部署上线·streamlit应用·streamlit部署
国科安芯21 小时前
AS32A601型MCU芯片flash模块的擦除和编程
java·linux·前端·单片机·嵌入式硬件·fpga开发·安全性测试
lsx20240621 小时前
CSS3 过渡
开发语言
青云交21 小时前
Java 大视界 -- Java 大数据机器学习模型在自然语言处理中的对话系统多轮交互优化与用户体验提升
java·大数据·机器学习·自然语言处理·对话系统·多轮交互
90后小陈老师21 小时前
记录一次Figma订阅被多扣费的教训
java·linux·数据库
风生u21 小时前
Go的并发(协程)
开发语言·后端·golang
计算机毕设指导621 小时前
基于微信小程序的心理咨询预约系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
YJlio21 小时前
Active Directory 工具学习笔记(10.2):AdExplorer 实战(二)— 对象 / 属性 / 搜索 / 快照
java·笔记·学习
青衫码上行21 小时前
【JavaWeb学习 | 第19篇】Filter过滤器
java·学习·servlet·tomcat