`

ReentrantLock互斥锁

 
阅读更多
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互斥锁详解

    主要介绍了Java多线程 ReentrantLock互斥锁详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java多线程并发编程(互斥锁Reentrant Lock)

    主要介绍了ReentrantLock 互斥锁,在同一时间只能被一个线程所占有,在被持有后并未释放之前,其他线程若想获得该锁只能等待或放弃,需要的朋友可以参考下

    详解Java多线程编程中互斥锁ReentrantLock类的用法

    Java多线程并发的程序中使用互斥锁有synchronized和ReentrantLock两种方式,这里我们来详解Java多线程编程中互斥锁ReentrantLock类的用法:

    locks框架_ReentrantLock.pdf

    解释为什么它被称为“可重入锁”,以及如何解决传统锁可能的问题。 ReentrantLock 的基本用法: 深入探讨如何使用 ReentrantLock 来保护共享资源。演示如何通过 lock 和 unlock 方法来实现线程的同步和互斥。 ...

    读写锁.txt

    ReentrantLock//互斥锁 class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    高级开发并发面试题和答案.pdf

    互斥锁(重量级锁)也称为阻塞同步、悲观锁; 为什么说重量级锁开销大呢; synchronize实现基础syn为什么一定有可重入特性; synchronized 实现可重入性; reenlock和synchronize区别; ReentrantLock如何实现可重入性...

    java并发编程面试题

    java并发编程 基础知识,守护线程与线程, 并行和并发有什么区别? 什么是上下文切换?...ReentrantLock(重入锁)实现原理与公平锁非公平锁区别什么是可重入锁(ReentrantLock)? ThreadLocal内存泄漏分析与

    基于redis实现分布式锁的原理与方法

    为了保证一个在高并发存场景下只能被同一个线程操作,java并发处理提供ReentrantLock或Synchronized进行互斥控制。但是这仅仅对单机环境有效。我们实现分布式锁大概通过三种方式。 redis实现分布式锁 数据库实现...

    去故新 Java线程新同步机制

    1、可重入锁ReentrantLock,相当于synchronized块,为临界区提供互斥访问机制。 (1) 相关的接口 创建一个可重入锁 Lock lock = new ReentrantLock(); 请求锁,如果锁被当前另一个线程持有,则阻塞。 void ...

    locks框架:接口.pdf

    可重入性和重入锁: 解释 Lock 接口的可重入性,讲解同一个线程多次获取锁的机制,避免死锁。介绍 ReentrantLock 的实现原理。 Condition 条件变量: 介绍 Lock 接口中的 Condition,它可以实现更复杂的线程等待和...

    java多线程安全性基础介绍.pptx

    关键共享资源上互斥,变并发为串行即同步 锁 分类 显示锁 Lock Lock是个接口 实现类 ReentrantLock 可重入锁 ReentrantReadWriteLock.ReadLock ReentrantReadWriteLock.WriteLock 隐式锁(内置锁) ...

    个人总结的深入java多线程开发

    7)ReentrantLock可重入的互斥锁定 Lock 32 8)阻塞队列BlockingQueue 34 9)已完成任务队列CompletionService 36 10)计时器CountDownLatch 37 11)周期性同步工具CyclicBarrier 38 12)异步计算的结果Future 40 13)安排...

    java核心知识点整理.pdf

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics