Java并发-ReentrantLock

什么是ReentrantLock?

1、ReentrantLock可重入锁:一个线程获取了锁,当它想再次想获取锁的时候不用等待可以直接获取锁;
2、公平锁:按请求锁的顺序分配,保证线程会获取锁,性能比公平锁低;
2、非公平锁:不按照请求锁的顺序分配,不保证线程会获取锁,性能比公平锁高;
ReentrantLock是基于AQS,在并发编程中它可以实现公平锁非公平锁来对共享资源进行同步,
同时,和synchronized异常,ReentrantLock至此可重入,除此之外ReentrantLock在调度上更加灵活,至此丰富的功能。
在这里插入图片描述

Lock接口

Lock的意义在于提供了区别于Synchronized的另外一种具有广泛操作的同步方式,它能支持更多灵活的结构

public interface Lock {
/**用于获取锁,假如当前资源被其他线程占用,将会等待直到获取锁*/
    void lock();
 /**和lock()方法一样,区别在于如果在等待获取锁的时候被中断,将会退出等待,并抛出异常*/
    void lockInterruptibly() throws InterruptedException;
/**尝试获取锁,如果获取并立即返回,返回值为boolean代表是否获取锁*/
    boolean tryLock();
    /**在一段时间内获取锁,假如被终端将会抛出异常*/
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
   /**释放锁*/
    void unlock();
/**新建一个绑定在当前Lock上的Condition对象
Condition对象表示一个等待状态
场景:获取锁的线程可能需要等待一些条件的完成才能继续执行
这样他就可以通过await()方法注册在condition对象上进行等待
然后通过condition的signal()方法将其唤醒
可以分组唤醒,丰富线程调度*/
    Condition newCondition();
}

ReentrantLock 核心方法

ReentrantLock构造方法

默认实现非公平锁,还可以通过传入一个布尔值选择公平锁

    public ReentrantLock() {
        sync = new NonfairSync();
    }

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

nonfairTryAcquire()非公平的尝试获取锁

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            /**首先获取status:status为0的话代表当前锁状态为空闲*/
            int c = getState();
            /**当锁为空闲可以通过一次cas来原子的更改status*/
            if (c == 0) {
            /**通过cas来更改status的状态*/
                if (compareAndSetState(0, acquires)) {
                /**如果更改成功就获取了锁,将当前线程改为独占线程,并返回true*/
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            /**当status不为0的话,就判断当前线程是否为独占线程
            可重入性:单个线程执行时候,重新进入同一个子程序,任然是线程安全的,一个线程获取了锁,可以不用等待再次获取锁*/
            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;
        }

NonfairSync 非公平锁

重写了AQS lock于tryAcquire方法,
非公平锁有两次获取锁的机会,如果获取失败就变成公平锁,在队列中排队

    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;
        final void lock() {
        /**通过CAS的方式获取锁,如果获取成功,设置为独占状态*/
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
            /**获取失败就调用AQS中的acquire方法,在acquire方法中还用一次尝试获取锁*/
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
        /**插队尝试获取锁*/
            return nonfairTryAcquire(acquires);
        }
    }

FairSync公平锁

    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            /**当该线程前面没有其他线线程可以通过CAS去获取锁*/
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            /**如果当给钱线程以及获取了锁,对status进行累加*/
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

java中断机制

1、interrupt
interrupt 方法用于中断线程。调用该方法的线程的状态为将被置为”中断”状态。通过修改一个标志中断的布尔值
注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监
视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出
interruptedException 的方法)就是在监视线程的中断状态,一旦线程的中断状
态被置为“中断状态”,就会抛出中断异常。
2、interrupted
线程在排队等待锁的时候如果调用了interrupted方法,就会放弃等待锁,直接抛出异常
查询当前线程的中断状态,并且清除原状态。如果一个线程被中断了,第一次调
用 interrupted 则返回 true,第二次和后面的就返回 false 了。
3、isInterrupted
仅仅是查询当前线程的中断状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值