ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”。它添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。
ReentrantLock在同一个时间点只能被一个线程获取(当某线程获取到“锁”时,其它线程就必须等待)。
ReentrantLock分为“公平锁”和“非公平锁”。在公平锁上,线程按照他们发出请求的顺序获取锁,但在非公平锁上则允许“插队”。
ReentraantLock是通过一个FIFO的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。
1、防止重复执行(忽略重复触发)
ReentrantLock lock = new ReentrantLock(); if (lock.tryLock()) { //如果已经被lock,则立即返回false不会等待,达到忽略操作的效果 try { //操作 } finally { lock.unlock(); } }
2、同步执行,类似synchronized
ReentrantLock lock = new ReentrantLock(); //参数默认false,不公平锁 ReentrantLock lock = new ReentrantLock(true); //公平锁 lock.lock(); //如果被其它资源锁定,会在此等待锁释放,达到暂停的效果 try { //操作 } finally { lock.unlock(); }
3、尝试等待执行
ReentrantLock lock = new ReentrantLock(true); //公平锁 try { if (lock.tryLock(5, TimeUnit.SECONDS)) { //如果已经被lock,尝试等待5s,看是否可以获得锁,如果5s后仍然无法获得锁则返回false继续执行 try { //操作 } finally { lock.unlock(); } } } catch (InterruptedException e) { e.printStackTrace(); //当前线程被中断时(interrupt),会抛InterruptedException }
4、可中断锁的同步执行
ReentrantLock lock = new ReentrantLock(true); //公平锁 lock.lockInterruptibly(); try { //操作 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
Condition:
Condition是在java1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作。相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。
调用Condition的await()和signal()方法,都必须在lock保护之内。
Conditon中的await()对应Object的wait(),Condition中的signal()对应Object的notify(),Condition中的signalAll()对应Object的notifyAll()。wait和notify是和synchronized关键字配合使用的。
public class MessageService { private Lock lock = new ReentrantLock(); private boolean flag = false; private Condition condition = lock.newCondition(); private int number = 1; /** * 生产者 */ public void produce() { lock.lock(); try { while (flag == true) { //等待通知进行生产 condition.await(); } System.out.println(Thread.currentThread().getName() + "-----生产-----"); number++; System.out.println("number: " + number); TimeUnit.MILLISECONDS.sleep(1000); flag = true; //通知进行消费 condition.signalAll(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } /** * 消费者 */ public void consume() { lock.lock(); try { while (flag == false) { //等待通知进行消费 condition.await(); } System.out.println(Thread.currentThread().getName() + "-----消费-----"); number--; System.out.println("number: " + number); TimeUnit.MILLISECONDS.sleep(1000); flag = false; //通知进行生产 condition.signalAll(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } }
相关推荐
ReentrantLock的使用及注意事项
Java中的ReentrantLock是线程安全编程中的一种高级锁机制,它属于Lock接口的一个实现,提供了比synchronized更丰富的功能和更高的灵活性。ReentrantLock的名字来源于它的可重入性,这意味着一个线程可以多次获取同一...
Java中的显示锁ReentrantLock使用与原理详解 Java中的显示锁ReentrantLock是Java concurrency API中的一种同步机制,用于解决多线程安全问题。ReentrantLock是Java 5中引入的,它是一种可重入锁,允许同一个线程多...
默认情况下,ReentrantLock 使用非公平锁,它的效率和吞吐量都比公fair锁高的多。 获取锁的过程中,ReentrantLock 使用了 AQS 的 acquiring 机制。首先,ReentrantLock 会调用 sync 的 lock 方法,而这个方法是一个...
Lock、Synchronized 和 ReentrantLock 的使用 Lock、Synchronized 和 ReentrantLock 是 Java 中三种常用的同步机制,每种机制都有其特点和使用场景。下面对这三种机制进行详细的分析和比较。 一、Synchronized ...
#### 3.2 ReentrantLock使用方式 - **创建实例**:通过new ReentrantLock()创建锁实例。 - **获取锁**:调用lock()方法获取锁。 - **释放锁**:调用unlock()方法释放锁。 #### 3.3 ReentrantLock源码分析 ...
ReentrantLock的lock方法使用CAS操作来尝试更新对象内的一个变量,如果更新成功,则将exclusiveOwnerThread变量设置为当前线程,然后lock方法会立刻返回。如果更新不成功,则调用acquire(1)方法。 ReentrantLock的...
《ReentrantLock源码详解与应用》 ReentrantLock,可重入锁,是Java并发编程中一个重要的锁实现,它提供了比synchronized更高级别的控制能力,包括公平性和非公平性选择。本文将深入探讨ReentrantLock的原理,特别...
`ReentrantLock`是Java并发编程中的一种高级锁机制,它是`java.util.concurrent.locks`包中的类,提供了比`...了解并熟练使用`ReentrantLock`能帮助开发者更好地解决并发问题,提高程序的并发性能和健壮性。
《ReentrantLock深度解析》 在Java并发编程中,ReentrantLock是JDK提供的一个可...在实际开发中,可以根据需求选择使用synchronized还是ReentrantLock,或者其他的并发控制手段,以达到最佳的并发性能和资源利用效率。
* ReentrantLock使用起来比较灵活,但是必须有释放锁的配合动作。 * ReentrantLock必须手动获取与释放锁,而synchronized不需要手动释放和开启锁。 volatile关键字的作用: * 保证可见性:volatile关键字可以确保...
本篇文章将深入探讨`ReentrantLock`的使用以及如何结合Lambda表达式来优化同步代码。 `ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个类,它是可重入的互斥锁,具备与`synchronized`相同的基本...
在Java多线程编程中,`ReentrantLock`和`synchronized`都是用于实现线程同步的重要工具,确保在并发环境中数据的一致性和正确性。两者虽然都能实现互斥访问,但在功能、性能以及使用场景上有所不同。下面我们将深入...
ReentrantLock使用AQS来实现锁的获取和释放,并提供了更加灵活的加锁机制。 ReentrantLock的优点包括: * 提供了更丰富的加锁机制,包括定时的锁等待、可中断的锁等待、公平锁、非阻塞结构的加锁等。 * 能够提供更...
java语言 并发编程 ReentrantLock与synchronized区别 详解
### ReentrantLock源码分析 #### 一、ReentrantLock简介 ReentrantLock是一个基于`AbstractQueuedSynchronizer`(AQS)实现的高级锁工具类。与传统的synchronized关键字相比,ReentrantLock提供了更多控制手段,比如...
本篇文章将深入探讨`ReentrantLock`的特性,功能以及如何使用。 ### 1. ReentrantLock简介 `ReentrantLock`是Java并发编程中的一种重要工具,它允许线程在已经获取锁的情况下再次获得同一把锁,而不必等待解锁。这...
本篇文章将深入探讨`ReentrantLock`的使用,它是Java并发包`java.util.concurrent.locks`中的一个高级锁机制,相比传统的`synchronized`关键字,提供了更丰富的功能和更灵活的控制。 `ReentrantLock`全称为可重入锁...
下面我们将详细介绍 ReentrantLock 的使用和实现原理。 一、ReentrantLock 的构造方法 ReentrantLock 提供了两个构造方法: 1. `public ReentrantLock()`: 这是 ReentrantLock 的默认构造方法,它会创建一个非...
70. 可重入锁ReentrantLock使用AQS(AbstractQueuedSynchronizer)实现,而synchronized使用内置机制。 71. AQS是一个抽象的同步队列,实现独占锁、读写锁等,通过维护一个状态和双端队列实现。 72. AQS的资源共享...