public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; // 内部类 private final Sync sync; //sync继承同步器,并生成模版 abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; // lock方法 abstract void lock(); // 非公平的获取锁,这样的性能会高 final boolean nonfairTryAcquire(int acquires) { // 获取当前线程 final Thread current = Thread.currentThread(); // 获取状态 int c = getState(); if (c == 0) { //如果当前没有锁的话,使用原子安全更新,如果状态为0,把之数值设为acquires if (compareAndSetState(0, acquires)) { // 设定获取锁的线程 setExclusiveOwnerThread(current); return true; } } // 如果当前线程为获取锁的线程 else if (current == getExclusiveOwnerThread()) { // 数值的变更,这里为了可重入,如果不能重入的话,递归方法无法被同步 int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); // 设置状态 setState(nextc); return true; } return false; } // 释放锁 protected final boolean tryRelease(int releases) { int c = getState() - releases; // 如果当前线程不是获取锁的线程,抛出异常 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { // 状态为0,则将对象内谁持有锁清空 free = true; setExclusiveOwnerThread(null); } // 否则,则对于重入锁,每次进行递减 setState(c); return free; } protected final boolean isHeldExclusively() { // 判断锁是否被当前线程锁持有 return getExclusiveOwnerThread() == Thread.currentThread(); } final ConditionObject newCondition() { // 返回一个等待通知组件 return new ConditionObject(); } final Thread getOwner() { // 获取线程锁的拥有者,如果状态为0,说明没有人持有锁,返回空,否则返回持有锁的线程 return getState() == 0 ? null : getExclusiveOwnerThread(); } final int getHoldCount() { //如果同步器在独占模式下被线程占用。返回状态,否则为0 return isHeldExclusively() ? getState() : 0; } final boolean isLocked() { // 如果线程的状态为0,说明没有人持有锁,否则锁被持有 return getState() != 0; } /** * Reconstitutes the instance from a stream (that is, deserializes it). */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } } // 非公平同步器 static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } // 公平同步器 static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } } // 默认使用的是非公平同步器 public ReentrantLock() { sync = new NonfairSync(); } public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); } // 同步器进行锁 public void lock() { sync.lock(); } // 同步器获取可中断锁 public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } // 获取非公平锁 public boolean tryLock() { return sync.nonfairTryAcquire(1); } // 同步器获取超时锁 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } // 同步器释放锁 public void unlock() { sync.release(1); } // 同步器返回组件 public Condition newCondition() { return sync.newCondition(); } // 获取锁被获取的次数 public int getHoldCount() { return sync.getHoldCount(); } // 判断锁事都被当前线程锁持有 public boolean isHeldByCurrentThread() { return sync.isHeldExclusively(); } //判断锁是否已被获取 public boolean isLocked() { return sync.isLocked(); } // 判断是否公平同步器 public final boolean isFair() { return sync instanceof FairSync; } // 获得拥有锁的线程 protected Thread getOwner() { return sync.getOwner(); } // 判断同步器的同步队列中是否有线程等待 public final boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } // 判断同步器的同步队列中是否包含某个线程 public final boolean hasQueuedThread(Thread thread) { return sync.isQueued(thread); } // 获得同步器同步队列的长度 public final int getQueueLength() { return sync.getQueueLength(); } // 返回同步器同步队列中所有线程 protected Collection<Thread> getQueuedThreads() { return sync.getQueuedThreads(); } // 判断组件是否有等待者 public boolean hasWaiters(Condition condition) { //判断为空,抛出异常 if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); } // 获取组件等待队列的长度 public int getWaitQueueLength(Condition condition) { if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); } // 获取等待队列的线程,主要是Condition组件中的等待线程 protected Collection<Thread> getWaitingThreads(Condition condition) { if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); } // toString方法 public String toString() { Thread o = sync.getOwner(); return super.toString() + ((o == null) ? "[Unlocked]" : "[Locked by thread " + o.getName() + "]"); } }
ReentrantLock锁与synchronized理论上相同,因为都是独占锁,而且可重入。
但是ReentrantLock锁必须手动的释放,否则会产生灾难,而synchronized在代码块结束的时候就把锁释放了。
synchronized ("a".getClass()){ synchronized ("b".getClass()){ } }
这个必须先放掉里面的锁,在释放外面的锁。
private static final ReentrantLock locka = new ReentrantLock(); private static final ReentrantLock lockb = new ReentrantLock(); public static void start() { locka.lock(); lockb.lock(); try { Thread.sleep(1000); } catch (Exception e) { } finally { lockb.unlock(); locka.unlock(); } }
可以定制化,无需释放内部锁在释放外部锁。如果没有定制化的话,推荐使用synchronized关键字
相关推荐
主要介绍了Java多线程 ReentrantLock互斥锁详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要介绍了ReentrantLock 互斥锁,在同一时间只能被一个线程所占有,在被持有后并未释放之前,其他线程若想获得该锁只能等待或放弃,需要的朋友可以参考下
Java多线程并发的程序中使用互斥锁有synchronized和ReentrantLock两种方式,这里我们来详解Java多线程编程中互斥锁ReentrantLock类的用法:
解释为什么它被称为“可重入锁”,以及如何解决传统锁可能的问题。 ReentrantLock 的基本用法: 深入探讨如何使用 ReentrantLock 来保护共享资源。演示如何通过 lock 和 unlock 方法来实现线程的同步和互斥。 ...
ReentrantLock//互斥锁 class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
互斥锁(重量级锁)也称为阻塞同步、悲观锁; 为什么说重量级锁开销大呢; synchronize实现基础syn为什么一定有可重入特性; synchronized 实现可重入性; reenlock和synchronize区别; ReentrantLock如何实现可重入性...
java并发编程 基础知识,守护线程与线程, 并行和并发有什么区别? 什么是上下文切换?...ReentrantLock(重入锁)实现原理与公平锁非公平锁区别什么是可重入锁(ReentrantLock)? ThreadLocal内存泄漏分析与
为了保证一个在高并发存场景下只能被同一个线程操作,java并发处理提供ReentrantLock或Synchronized进行互斥控制。但是这仅仅对单机环境有效。我们实现分布式锁大概通过三种方式。 redis实现分布式锁 数据库实现...
1、可重入锁ReentrantLock,相当于synchronized块,为临界区提供互斥访问机制。 (1) 相关的接口 创建一个可重入锁 Lock lock = new ReentrantLock(); 请求锁,如果锁被当前另一个线程持有,则阻塞。 void ...
可重入性和重入锁: 解释 Lock 接口的可重入性,讲解同一个线程多次获取锁的机制,避免死锁。介绍 ReentrantLock 的实现原理。 Condition 条件变量: 介绍 Lock 接口中的 Condition,它可以实现更复杂的线程等待和...
关键共享资源上互斥,变并发为串行即同步 锁 分类 显示锁 Lock Lock是个接口 实现类 ReentrantLock 可重入锁 ReentrantReadWriteLock.ReadLock ReentrantReadWriteLock.WriteLock 隐式锁(内置锁) ...
7)ReentrantLock可重入的互斥锁定 Lock 32 8)阻塞队列BlockingQueue 34 9)已完成任务队列CompletionService 36 10)计时器CountDownLatch 37 11)周期性同步工具CyclicBarrier 38 12)异步计算的结果Future 40 13)安排...
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................