java可重入锁ReentrantLock

ReentrantLock是一个可重入的独占锁,同一线程可重复获取锁的状态,该锁一次只能被一个线程所持有。

构造方法

ReentrantLock() :创建 ReentrantLock实例,随机分配使用权。
ReentrantLock(boolean fair) :创建具有公平政策的ReentrantLock实例,在锁上等待时间最长的线程将获取锁的使用权(先来先得)。

所有方法

int getHoldCount() 

查询当前线程持有这个锁的数量,每 lock.lock();一次该数量+1。

protected Thread getOwner() 

返回拥有该锁的线程,如果没有返回null,该方法是一个受保护的方法,需要使用一个类来extends ReentrantLock类,在继承类中操作。

protected Collection<Thread> getQueuedThreads() 

返回一个包含可能等待获取此锁的线程的集合。

int getQueueLength() 

返回等待获取此锁的线程数的估计值。因为当此方法遍历内部数据结构时,线程数可能会动态更改(其他获取集合或者数量的方法都会这样)。此方法设计用于监视系统状态,而不是用于同步控制。

protected Collection<Thread> getWaitingThreads(Condition condition) 

返回一个集合,包含可能在与此锁关联的给定条件下等待的线程集合。

int getWaitQueueLength(Condition condition) 

返回在与此锁关联的给定条件下等待的线程数的估计值。

boolean hasQueuedThread(Thread thread) 

查询给定线程是否正在等待获取此锁。

boolean hasQueuedThreads() 

查询是否有任何线程等待获取此锁。

boolean hasWaiters(Condition condition) 

查询是否有任何线程在与此锁关联的给定条件下等待。

boolean isFair() 

是公平锁返回true。

boolean isHeldByCurrentThread() 

查询当前线程是否持有此锁。

boolean isLocked() 

查询此锁是否由线程持有。

void lock() 

获取锁。

void lockInterruptibly() 

获取该锁除非当前线程是被interrupt()方法中断的。

Condition newCondition() 

返回一个用于这 Lock实例 Condition实例。

String toString() 

返回一个确定此锁的字符串,以及它的锁状态。

boolean tryLock() 

尝试获取锁,只有在调用时锁没有被另一个线程持有时才获取锁。。

boolean tryLock(long timeout, TimeUnit unit) 

如果在给定的等待时间内没有被其他线程持有,并且当前线程没有被interrupt()中断,则获取锁

void unlock() 

试图释放这个锁。

使用DEMO

	static AtomicInteger num = new AtomicInteger(0);
	//初始化可重入锁
	static Lock lock = new ReentrantLock();
	static Condition addCondition = lock.newCondition();
	static Condition subCondition = lock.newCondition();
	static int j = 0;
	 
    public static void main(String[] args) throws InterruptedException {
    	
        
        //初始化A线程
        Thread threadAdd = new Thread(new Runnable() {
            @Override
            public void run() {
                //需要先获得锁
                lock.lock();
                System.out.println("threadAdd:获得锁");
                try {
                    System.out.println("threadAdd:开始加");
                    //A线程先输出前3个数
                    while (true) {
                    	Thread.sleep(1000);
                    	while (num.intValue() < 10) {
                            num.incrementAndGet(); 
                        }
                    	System.out.println("threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行");
     	            	//输出到10时要signal,告诉threadSub线程可以开始了
     	            	subCondition.signal();
     	            	addCondition.await();
     	            	j++;
     	            	//跳出循环,并且通知subCondition继续
     	            	if(j>5) {
     	            		System.out.println("threadAdd:循环了5次了,不继续了,跳出循环让threadSub再继续执行");
     	            		subCondition.signal();
     	            		break;
     	            	}
					}
                } catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
                    lock.unlock();
                    System.out.println("threadAdd:释放lock");
                }
            }
        });
        
        Thread threadSub = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock.lock();
                    System.out.println("threadSub:获得锁");
                    while (true) {
                    	Thread.sleep(1000);
                    	while (num.intValue() > 0) {
                            num.decrementAndGet();
                        }
                        System.out.println("threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行");
                        addCondition.signal();
						subCondition.await();
						if(j>5) {
							System.out.println("threadSub:循环了5次了,我也不继续了,跳出循环");
     	            		break;
     	            	}
					}  
                } catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
                    lock.unlock();
                    System.out.println("threadSub:释放lock");
                }
                
            }
        });
        //启动两个线程
        threadAdd.start();
        Thread.sleep(1);
        threadSub.start();
    }

结果

threadAdd:获得锁
threadAdd:开始加
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:获得锁
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:已经加到10了,告诉threadSub开始,等待threadSub通知我再继续执行
threadSub:已经减到0了,告诉threadAdd开始,等待threadAdd通知我再继续执行
threadAdd:循环了5次了,不继续了,跳出循环让threadSub再继续执行
threadAdd:释放lock
threadSub:循环了5次了,我也不继续了,跳出循环
threadSub:释放lock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里藍天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值