`

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互斥锁详解 ReentrantLock是Java多线程编程中的一种锁机制,它可以实现线程之间的同步访问资源。ReentrantLock的主要特点是可以重入,即一个线程可以多次获得锁,而不需要释放锁。这种机制...

    Java concurrency之互斥锁_动力节点Java学院整理

    Java中的`ReentrantLock`类是互斥锁的一种实现,它是Java并发包(`java.util.concurrent.locks`)的一部分。 `ReentrantLock`提供了比Java内置的`synchronized`关键字更丰富的功能和更高的控制级别。它具有可重入性,...

    各种锁汇总,乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁、行级锁等

    在Java中,`ReentrantLock`是互斥锁的实现。 6. **读写锁**:读写锁允许多个读线程同时访问资源,但写线程独占资源。Java的`ReentrantReadWriteLock`提供这种功能,提高并发性能。 7. **分段锁**:当数据结构很大...

    多线程(11)ReentrantLock公平锁与非公平锁(修改)1

    在Java并发编程中,`ReentrantLock`是一个可重入的互斥锁,相比`synchronized`提供了更细粒度的控制以及更丰富的特性。`ReentrantLock`的公平性和非公平性是其重要的特性之一。在上述代码中,我们创建了一个`...

    Java使用synchronized实现互斥锁功能示例

    Java使用synchronized实现互斥锁功能示例 在Java编程语言中,synchronized关键字是实现互斥锁功能的主要手段。互斥锁是一种机制,用于控制多个线程访问共享资源的顺序,从而避免因为资源竞争而导致的程序错误。在...

    基于consul的分布式锁工具,包含:互斥锁、信号量等工具

    - **互斥锁**:互斥锁确保同一时间只有一个线程可以访问资源,其他试图获取锁的线程必须等待锁被释放。在Java中,通常通过`java.util.concurrent.locks.ReentrantLock`实现。 - **信号量**:信号量允许多个线程...

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

    9. **可读写的锁**:虽然ReentrantLock主要关注互斥锁,但Java并发包中还有ReentrantReadWriteLock,它提供了读写锁,允许多个读取线程同时访问资源,而写入操作仍然保持互斥。 总结来说,ReentrantLock提供了比...

    Java concurrency之互斥锁_动力节点Java学院

    `ReentrantLock`是一个可重入的互斥锁,这意味着一个线程可以多次获取同一把锁,即在获取锁后,线程可以再次请求同一把锁而不被阻塞。这种设计允许在复杂的同步逻辑中避免死锁的发生。`ReentrantLock`有两种模式:...

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

    ReentrantLock 是 Java 中的一种高级锁机制,属于互斥锁的一种,能够在多线程并发编程中发挥重要作用。下面将详细介绍 ReentrantLock 的概念、特点、用法和优缺点。 一、ReentrantLock 简介 ReentrantLock 是 Java...

    prioritylock:一个互斥锁,它将确保优先级值较高的请求在低优先级的请求获得锁之前先获得该锁

    在Java中,`java.util.concurrent.locks.Lock`接口及其实现如`ReentrantLock`提供了互斥锁的功能。 而PriorityLock则在基本的互斥锁基础上增加了一层优先级判断。在默认情况下,所有线程平等竞争锁,但PriorityLock...

    详解java中的互斥锁信号量和多线程等待机制

    static class MyThread extends Thread{ ...} 在这个例子中,我们使用 ReentrantLock 来实现互斥锁,通过 tryLock() 方法来获取锁,如果获取成功,则执行同步代码,否则,不执行同步代码。 信号量相当于一个计数器...

    如何实现程序互斥运行

    互斥锁(Mutex)是一种同步原语,用于控制对共享资源的访问。当一个线程获得锁后,其他试图获取该锁的线程将会被阻塞,直到该锁被释放。这样可以确保在任何时候只有一个线程能够访问受保护的代码段或数据。 二、...

    ReentrantLock解析

    在Java并发编程中,ReentrantLock是JDK提供的一个可重入互斥锁,它是java.util.concurrent.locks包下的核心类。与synchronized关键字相比,ReentrantLock提供了更高的灵活性,如尝试加锁、定时加锁和公平锁等功能。...

    Java多线程之ReentrantLock与Condition - 平凡希 - 博客园1

    Java中的`ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个高级锁机制,它是可重入的互斥锁,具有与`synchronized`关键字相似的同步性,但提供了更多的灵活性和控制功能。本篇文章将深入探讨`...

    第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()1

    ReentrantLock是由Java提供的可重入互斥锁,支持公平锁和非公平锁两种模式。非公平锁的特性是获取锁的线程不论先后,都有机会获得锁,而公平锁则遵循先进先出的原则,保证线程按照请求锁的顺序进行。 2. **...

    ReentrantLock与synchronized

    总结来说,`synchronized`适用于简单的同步需求,而`ReentrantLock`在需要更细粒度控制、中断锁、公平性等高级特性的场合更为适用。在实际编程中,根据具体需求选择合适的方式,能有效提升并发程序的稳定性和性能。...

    线程间资源互斥与通信(生产者消费者)

    在Java中,可以使用`synchronized`关键字或`java.util.concurrent.locks.ReentrantLock`类来实现互斥锁。 2. **信号量(Semaphore)**:除了互斥锁,还可以使用信号量来控制对资源的访问。信号量维护了一个计数器,...

    使用ReentrantLock和Lambda表达式让同步更

    `ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个类,它是可重入的互斥锁,具备与`synchronized`相同的基本行为,但增加了许多高级功能。以下是一些`ReentrantLock`的主要特性: 1. **可重入性**...

    Multhread.rar_互斥

    例如,在Java中,可以使用`synchronized`关键字或者`java.util.concurrent.locks.ReentrantLock`类来实现互斥锁。 在"Multhread"这个示例中,可能包含了一段或多段代码,展示了如何在多线程环境中正确地使用互斥锁...

Global site tag (gtag.js) - Google Analytics