Java锁系列教程之独占式锁
在Java并发编程中,锁是一个很重要的对象。Java中锁有两种:隐式锁和显式锁。使用synchronized关键字的锁是隐式锁。因为锁的申请和释放都是由JVM来维护的,不用我们来手动处理。使用Java并发包locks包下的锁,需要使用者手动申请和手动关闭。这种形式是显式锁。如果按照多个线程能不能共享同一个锁(资源)来分的话,可以分为独占式(排他)锁和共享锁。其中synchronized关键字的锁和ReentrantLock锁的锁都是独占式锁。
通过前面三篇文章的学习,我们知道了同步组件基础框架-AbstractQueuedSynchronizer(AQS) 同步器。在同步器的方法中有两种方式获取锁:独占式和共享式锁。我们先来学习独占式锁-ReentrantLock。
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第四篇:《Java并发包下锁学习第四篇:ReentrantLock》。
编辑
ReentrantLock使用语法
我们知道并发包下的lock是显式锁,需要手动获取锁和手动释放锁。所以语法如下:
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
//TODO
}finally {
lock.unlock();
}
获取锁:lock.lock();
释放锁:lock.unlock();
在try中获取到锁;在finally中释放锁。
因为必须释放锁。所以,必须在finally中进行释放锁操作。而且释放锁操作必须放在finally的第一行。
独占式锁理解:
生活中的例子:
在自动ATM机上取钱的时候,我们需要排队,当一个人在操作ATM机取钱的时候,下一个人就需要在ATM机黄线外面等待(排除和取钱人一起去的人)。假设路人甲在操作ATM机的时候,我们其他后面排队的人是不是需要等待着,路人甲从ATM机区域出来后才可以进行操作ATM机。这个操作过程如果放在我们多线程并发角度来思考的话:共享数据是ATM机,多个线程是多个存取钱的人。当路人甲在操作ATM机的时候路人甲获取到ATM机操作权限可以理解为lock.lock()操作。这个时候,共享数据ATM机就会被路人甲独自一个人占用了(独占式获取到了共享数据(或者是锁))。当路人甲操作完离开ATM机这个操作可以理解为lock.unlock()操作。
从上了生活例子中我们可以这么理解独占式锁,所谓的独占式锁就是同一时刻只能有且只有一个线程获取到锁且操作成功,其他线程只能等待释放锁后,在进行操作。
需要说明的是,在Java中隐式锁(synchronized关键字修饰的)也是独占式锁的一种体现。
使用方法一:独占非公平演示
需求:使用三个线程,调用一个方法,在方法内睡眠2s.代码下图:
查看运行结果:
线程2开始获取锁。
线程3开始获取锁。
线程1开始获取锁。
线程2获取到了锁。开始做其他的操作了====do..........
======关闭锁=======
线程3获取到了锁。开始做其他的操作了====do..........
======关闭锁=======
线程1获取到了锁。开始做其他的操作了====do..........
======关闭锁=======
从上图运行结果,我们可以分析出:
1:线程的顺序和我们线程运行的顺序不一致
2:每次只能有一个线程执行完关闭锁之后,其他线程才可以接着使用。
从示例代码,我们可以得到如下总结:
1:reentrantLock是独占式锁;
2:默认情况下不能保证获取锁的顺序和线程执行顺序的一致性。
如果想要保证线程执行顺序和获取锁的顺序一致性,也是可以操作的。在下一篇文章中,凯哥将讲解怎么操作。
欢迎来聊
相关推荐
此外,Java还提供了多种方式来处理锁可能导致的问题,比如实现公平锁可以保证线程按照请求锁的顺序来获得锁;使用Lock接口提供的tryLock()方法可以尝试非阻塞地获取锁。 通过以上对Java锁机制的详细介绍,可以看出...
- 读写锁分为读锁(共享锁)和写锁(独占锁)。读锁允许多个线程同时读取数据,而写锁只允许一个线程进行写操作。 - 当一个线程持有写锁时,其他线程无法获取读锁或写锁,保证了写操作的互斥性。 - 当一个线程...
非公平锁则不保证线程获取锁的顺序,它允许正在释放锁的线程在其释放后立即重新获取锁,而不必等待队列中的其他线程。这种方式通常能够提高性能,但由于它不保证公平性,因此可能导致某些线程长期得不到锁,从而出现...
公平锁与非公平锁 `synchronized`默认是非公平锁,这意味着在释放锁之后,下一个获取锁的线程并不一定是等待时间最长的那个。不过,`ReentrantLock`类支持设置公平锁,这使得锁的分配更加公平。 #### 五、锁的...
总之,理解并正确使用MySQL的共享锁和独占锁是保证数据库并发操作安全和高效的关键。开发者需要根据业务需求和系统性能考虑锁的粒度、锁的获取与释放时机,以及如何有效避免死锁,从而实现高效且一致的数据访问。
本篇章节主要讲解了 Java 中的并发编程相关知识,包括乐观锁、公平锁、非公平锁、独占锁和共享锁等概念。 首先,介绍了乐观锁的概念,乐观锁是一种无锁机制,通过在表中添加版本号或业务状态来实现锁定。这种锁定...
Java的ReentrantLock默认是非公平锁,可以通过构造函数参数设置为公平锁。 6. **分段锁** - 分段锁是一种优化策略,主要用于HashMap和ConcurrentHashMap中,将大锁分割成多个小锁,从而减少锁竞争,提高并发性能。...
- **显式锁**:如`java.util.concurrent.locks.Lock`接口及其实现,如`ReentrantLock`,提供了更复杂的锁操作,如可中断锁等待、公平锁等。 - **读写锁**:`ReentrantReadWriteLock`允许多个读取者同时访问,但...
在MySQL中,最基本和常见的两种锁类型是共享锁(Shared Lock)和独占锁(Exclusive Lock),也被简称为S锁和X锁。 共享锁(S锁)允许事务读取一行数据,其他事务也可以同时读取这行数据,但不能修改。也就是说,...
根据给定文件的信息,我们可以深入理解AQS(AbstractQueuedSynchronizer)独占锁之ReentrantLock的源码分析及其实现原理。这不仅包括ReentrantLock本身的特性,还包括了其背后的AQS框架是如何工作的。 ### 一、管程...
Java锁机制是Java多线程编程中的核心概念之一,其主要目的是确保在多线程环境下,多个线程能够安全地访问共享资源,避免数据不一致的问题。Java锁机制的发展历经了多个版本的改进,尤其是Java 5.0引入的显示锁...
`ReentrantLock`有两种模式:公平锁和非公平锁。 - 公平锁:遵循先来后到的原则,等待最久的线程会首先获得锁。公平锁通过维护一个FIFO(先进先出)的等待队列来实现这一特性。 - 非公平锁:线程获取锁的顺序不确定...
除了上述锁,Java并发库还提供了其他类型的锁,如可重入锁(ReentrantLock)、读写锁(ReadWriteLock)、公平锁与非公平锁、条件变量(Condition)等。这些锁各自有不同的特点和适用场景。例如,读写锁允许多个读取...
- ReentrantLock:作为独占锁,ReentrantLock提供了公平和非公平两种模式,支持锁的可重入性,具备与`synchronized`相似的功能,但提供了更多的控制选项。 理解并熟练掌握这些锁机制,可以帮助开发者更好地设计和...
它支持公平锁和非公平锁,并且提供尝试获取锁、可中断锁等待、定时锁等待等特性。 - **读写锁(ReadWriteLock)**:ReentrantReadWriteLock是Lock的一个实现,分为读锁(ReadLock)和写锁(WriteLock),允许多个读...
可重入锁支持公平锁和非公平锁模式,允许锁的持有者再次获取锁(即重入),并且可以实现锁的尝试获取、定时获取和中断获取。 3. **读写锁(ReadWriteLock)**:读写锁也是`java.util.concurrent.locks`的一部分,它...
1. **Lock接口**:Lock提供了比`synchronized`更细粒度的锁控制,包括公平锁和非公平锁、可中断锁、尝试获取锁等功能。例如,`ReentrantLock`实现了Lock接口,支持重入和公平/非公平模式。 2. **ReadWriteLock接口**...
在Java编程语言中,文件锁是一种用于控制对...总的来说,理解并熟练使用Java中的文件锁对于构建高效且可靠的文件操作程序至关重要。合理利用文件锁,可以确保在并发环境下数据的一致性和完整性,避免不必要的数据冲突。
1. **公平锁 / 非公平锁** - **公平锁** 保证了等待锁的线程按照申请顺序获得锁,避免了饥饿现象。 - **非公平锁** 允许线程抢占,可能导致优先级反转或饥饿,但其吞吐量通常高于公平锁。Java中的`ReentrantLock`...
然而,synchronized锁有一些限制,比如它不提供公平性保证(即线程获取锁的顺序可能与它们请求锁的顺序不同),也不支持尝试获取锁、可中断锁等待以及定时锁等待等功能。这些限制可以通过使用ReentrantLock类来克服...