java 银行并发_java并发编程——通过ReentrantLock,Condition实现银行存取款

本文介绍了Java并发编程中Lock接口的使用,特别是ReentrantLock和Condition。相较于内置的synchronized,ReentrantLock提供了更灵活的锁控制,如可重入、可判断和公平性。通过示例展示了如何使用ReentrantLock和Condition实现银行账户的存取款操作,确保线程安全。文章还讨论了公平锁和非公平锁的区别,并通过ArrayBlockingQueue展示了ReentrantLock和Condition在生产者消费者模型中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 并发编程系列文章

java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。该框架允许更灵活地使用锁和条件,但以更难用的语法为代价。

Lock 接口支持那些语义不同(重入、公平等)的锁规则,可以在非阻塞式结构的上下文(包括 hand-over-hand 和锁重排算法)中使用这些规则。主要的实现是 ReentrantLock。

ReadWriteLock 接口以类似方式定义了一些读取者可以共享而写入者独占的锁。此包只提供了一个实现,即 ReentrantReadWriteLock,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的、适用于非标准要求的实现。

以下是locks包的相关类图:

47e356737fbcb0cd5234a218bf6f7d8f.png

在之前我们同步一段代码或者对象时都是使用 synchronized关键字,使用的是Java语言的内置特性,然而 synchronized的特性也导致了很多场景下出现问题,比如:

在一段同步资源上,首先线程A获得了该资源的锁,并开始执行,此时其他想要操作此资源的线程就必须等待。如果线程A因为某些原因而处于长时间操作的状态,比如等待网络,反复重试等等。那么其他线程就没有办法及时的处理它们的任务,只能无限制的等待下去。如果线程A的锁在持有一段时间后可自动被释放,那么其他线程不就可以使用该资源了吗?再有就是类似于数据库中的共享锁与排它锁,是否也可以应用到应用程序中?所以引入Lock机制就可以很好的解决这些问题。

Lock提供了比 synchronized更多的功能。但是要注意以下几点:

1. Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;

2. Lock和synchronized有一点非常大的不同,采用 synchronized不需要用户去手动释放锁,当synchronized方法或者 synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而 Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。

3. synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;

4. 用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;

总结: synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)

一、可重入锁 ReentrantLock

想到锁我们一般想到的是同步锁即 Synchronized,这里介绍的可重入锁ReentrantLock的效率更高。IBM对于可重入锁进行了一个介绍:JDK 5.0 中更灵活、更具可伸缩性的锁定机制

这里简单介绍下可重入锁的分类:(假设线程A获取了锁,现在A执行完成了,释放了锁同时唤醒了正在等待被唤醒的线程B。但是,A执行唤醒操作到B真正获取锁的时间里可能存在线程C已经获取了锁,造成正在排队等待的B无法获得锁)

1) 公平锁:

由于B先在等待被唤醒,为了保证公平性原则,公平锁会先让B获得锁。

2) 非公平锁

不保证B先获取到锁对象。

这两种锁只要在构造ReentrantLock对象时加以区分就可以了,当参数设置为true时为公平锁,false时为非公平锁,同时默认构造函数也是创建了一个非公平锁。

private Lock lock = new ReentrantLock(true);

ReentrantLock的公平锁在性能和实效性上作了很大的牺牲,可以参考IBM上发的那篇文章中的说明。

二、条件变量 Condition

Condition是java.util.concurrent.locks包下的一个接口,  Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。为了避免兼容性问题,Condit

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值