资源预览内容
第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
第9页 / 共11页
第10页 / 共11页
亲,该文档总共11页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Java 多线程系列-“JUC 锁”02 之 互斥锁ReentrantLock 本章对 ReentrantLock 包进行基本介绍,这一章主要对 ReentrantLock 进行概括性的介绍,内容包括:ReentrantLock 介绍ReentrantLock 函数列表ReentrantLock 示例在后面的两章,会分别介绍 ReentrantLock 的两个子类(公平锁和非公平锁)的实现原理。转载请注明出处:http:/www.cnblogs.com/skywang12345/p/3496101.htmlReentrantLock 介 绍ReentrantLock 是一个可重入的互斥锁,又被称为“独占锁 ”。顾名思义,ReentrantLock 锁在同一个时间点只能被一个线程锁持有;而可重入的意思是,ReentrantLock 锁,可以被单个线程多次获取。ReentrantLock 分为“公平锁”和“非公平锁”。它们的区别体现在获取锁的机制上是否公平。“锁”是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock 在同一个时间点只能被一个线程获取(当某线程获取到“锁”时,其它线程就必须等待);ReentraantLock 是通过一个 FIFO 的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。ReentrantLock 函 数 列 表/ 创建一个 ReentrantLock ,默认是“非公平锁”。ReentrantLock()/ 创建策略是 fair 的 ReentrantLock。fair 为 true 表示是公平锁,fair 为 false 表示是非公平锁。ReentrantLock(boolean fair)www.qqtop2.com / 查询当前线程保持此锁的次数。int getHoldCount()/ 返回目前拥有此锁的线程,如果此锁不被任何线程拥有,则返回 null。protected Thread getOwner()/ 返回一个 collection,它包含可能正等待获取此锁的线程。protected Collection getQueuedThreads()/ 返回正等待获取此锁的线程估计数。int getQueueLength()/ 返回一个 collection,它包含可能正在等待与此锁相关给定条件的那些线程。protected Collection getWaitingThreads(Condition condition)/ 返回等待与此锁相关的给定条件的线程估计数。int getWaitQueueLength(Condition condition)/ 查询给定线程是否正在等待获取此锁。boolean hasQueuedThread(Thread thread)/ 查询是否有些线程正在等待获取此锁。boolean hasQueuedThreads()/ 查询是否有些线程正在等待与此锁有关的给定条件。boolean hasWaiters(Condition condition)/ 如果是“公平锁” 返回 true,否则返回 false。boolean isFair()/ 查询当前线程是否保持此锁。boolean isHeldByCurrentThread()/ 查询此锁是否由任意线程保持。boolean isLocked()/ 获取锁。void lock()/ 如果当前线程未被中断,则获取锁。void lockInterruptibly()/ 返回用来与此 Lock 实例一起使用的 Condition 实例。Condition newCondition()/ 仅在调用时锁未被另一个线程保持的情况下,才获取该锁。boolean tryLock()/ 如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁。http:/wangming.78name.com boolean tryLock(long timeout, TimeUnit unit)/ 试图释放此锁。void unlock()ReentrantLock 示 例通过对比“示例 1”和“示例 2”,我们能够清晰的认识 lock 和 unlock 的作用示例 11 import java.util.concurrent.locks.Lock;2 import java.util.concurrent.locks.ReentrantLock;3 4 / LockTest1.java5 / 仓库6 class Depot 7 private int size; / 仓库的实际数量8 private Lock lock; / 独占锁9 10 public Depot() 11 this.size = 0;12 this.lock = new ReentrantLock();13 14 15 public void produce(int val) 16 lock.lock();17 try 18 size += val;19 System.out.printf(%s produce(%d) size=%dn, 20 Thread.currentThread().getName(), val, size);21 finally 22 lock.unlock();23 24 25 26 public void consume(int val) 27 lock.lock();28 try 29 size -= val;30 System.out.printf(%s consume(%d) size=60Thread-1 produce(120) size=180Thread-3 consume(150) size=50结果分析:(01) Depot 是个仓库。通过 produce()能往仓库中生产货物,通过 consume()能消费仓库中的货物。通过独占锁 lock 实现对仓库的互斥访问:在操作(生产/消费)仓库中货品前,会先通过 lock()锁住仓库,操作完之后再通过 unlock()解锁。(02) Producer 是生产者类。调用 Producer 中的 produce()函数可以新建一个线程往仓库中生产产品。(03) Customer 是消费者类。调用 Customer 中的 consume()函数可以新建一个线程消费仓库中的产品。(04) 在主线程 main 中,我们会新建 1 个生产者 mPro,同时新建 1 个消费者 mCus。它们分别向仓库中生产/消费产品。根据 main 中的生产/ 消费数量,仓库最终剩余的产品应该是 50。运行结果是符合我们预期的!这个模型存在两个问题:(01) 现实中,仓库的容量不可能为负数。但是,此模型中的仓库容量可以为负数,这与现实相矛盾!(02) 现实中,仓库的容量是有限制的。但是,此模型中的容量确实没有限制的!这两个问题,我们稍微会讲到如何解决。现在,先看个简单的示例 2;通过对比“示例 1”和“示例 2”,我们能更清晰的认识 lock(),unlock()的用途。示例 21 import java.util.concurrent.locks.Lock;2 import java.util.concurrent.locks.ReentrantLock;3 4 / LockTest2.java5 / 仓库6 class Depot 7 private int size; / 仓库的实际数量8 private Lock lock; / 独占锁9 10 public Depot() 11 this.size = 0;12 this.lock = new ReentrantLock();13 14 15 public void produce(int val) 16 / lock.lock();17 / try 18 size += val;19 System.out.printf(%s produce(%d) size=%dn, 20 Thread.currentThread().getName(), val, size);21 / catch (InterruptedException e) 22 / finally 23 / lock.unlock();24 / 25 26 27 public void consume(int val) 28 / lock.lock();29 / try 30 size -= val;31 System.out.printf(%s consume(%d) size=-60Thread-4 produce(110) size=50Thread-2 consume(90) size=-60Thread-3 consume(150) 0) 28 / 库存已满时,等待“消费者 ”消费产品。29 while (size = capacity)30 fullCondtion.await();31 / 获取“实际生产的数量”( 即库存中新增的数量 )32 / 如果“库存”+“想要生产的数量”“总的容量”,则“实际增量”=“总的容量”-“当前容量”。(此时填满仓库)33 / 否则“实际增量”=“想要生产的数量”34 int inc = (size+left)capacity ? (capacity-size) : left;35 size += inc;36 left -= inc;37 System.out.printf(%s produce(%3d) left=%3d, inc=%3d, size=%3dn, 38 Thread.currentThread().getName(), val, left, inc, size);39 / 通知“消费者”可以消费了。40 emptyCondtion.signal();41 42 catch (InterruptedException e) 43 finally 44 lock.unlock()
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号