Lock和Condition在JDK中LinkedBlockingQueue的应用
Lock和Condition在JDK中LinkedBlockingQueue的应用,核心源码注释解析如下:
import java.util.concurrent.LinkedBlockingQueue.Node;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; /**
* LinkedBlockingQueue核心方法源码分析
*
*
*/
public class LinkedBlockingQueue { /** Current number of elements */
//使用AtomicInteger的原因是:LinkedBlockingQueue的take和put使用的是两把锁。所以需要对count进行同步。
//同时count使用AtomicInteger可以解决take和put的冲突操作
private final AtomicInteger count = new AtomicInteger(0); /** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock(); /** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition(); //绑定takeLock /** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock(); /** Wait queue for waiting puts */
private final Condition notFull = putLock.newCondition();//绑定putLock /**
* Inserts the specified element at the tail of this queue, waiting if
* necessary for space to become available.
*
* @throws InterruptedException
* {@inheritDoc}
* @throws NullPointerException
* {@inheritDoc}
*/
public void put(E e) throws InterruptedException {
if (e == null)
throw new NullPointerException();
// Note: convention in all put/take/etc is to preset local var
// holding count negative to indicate failure unless set.
int c = -1;
Node<E> node = new Node(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
/*
* Note that count is used in wait guard even though it is not
* protected by lock. This works because count can only decrease at
* this point (all other puts are shut out by lock), and we (or some
* other waiting put) are signalled if it ever changes from
* capacity. Similarly for all other uses of count in other wait
* guards.
*/
while (count.get() == capacity) {
notFull.await(); //绑定putLock
}
enqueue(node);
// 此处 c =size - 1(size为容器实际大小)
c = count.getAndIncrement();
if (c + 1 < capacity) //c+1 =size-1+1 =size ,如果c + 1 =size < capacity 的话
notFull.signal(); //唤醒其他生产者生产数据
} finally {
putLock.unlock();
}
if (c == 0) //c=size-1==0,就是size==1?如果size=1代表还有元素,通知消费者生产数据
signalNotEmpty(); //notEmpty.signal();
} /**
* Signals a waiting take. Called only from put/offer (which do not
* otherwise ordinarily lock takeLock.)
*/
private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
notEmpty.signal(); //绑定takeLock
} finally {
takeLock.unlock();
}
} public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {
notEmpty.await(); //绑定takeLock
}
x = dequeue();
// 有点绕:获取当前count的值,然后减1。
c = count.getAndDecrement();
//而此时由于x = dequeue()代码消费了一个数据,所以c=size+1
if (c > 1)//当前c=size+1>1的话,则就是size>0.所以此时就是有元素的,唤醒其他消费者消费数据
notEmpty.signal(); //绑定takeLock
} finally {
takeLock.unlock();
}
if (c == capacity) //c = size +1 ==capacity 所以size =capacity-1,则容器还没有满,所以通知生产者生产数据
signalNotFull(); // 调用notFull.signal();
return x;
} /**
* Signals a waiting put. Called only from take/poll.
*/
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
notFull.signal(); //绑定putLock
} finally {
putLock.unlock();
}
}
}
Lock和Condition在JDK中LinkedBlockingQueue的应用的更多相关文章
- Lock和Condition在JDK中ArrayBlockingQueue的应用
ArrayBlockingQueue的实现思路简单描述,ArrayBlockingQueue的底对于互斥访问使用的一个锁.细节参考源码take和put方法: import java.util.conc ...
- Java中的线程--Lock和Condition实现线程同步通信
随着学习的深入,我接触了更多之前没有接触到的知识,对线程间的同步通信有了更多的认识,之前已经学习过synchronized 实现线程间同步通信,今天来学习更多的--Lock,GO!!! 一.初时Loc ...
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...
- Java并发(10)- 简单聊聊JDK中的七大阻塞队列
引言 JDK中除了上文提到的各种并发容器,还提供了丰富的阻塞队列.阻塞队列统一实现了BlockingQueue接口,BlockingQueue接口在java.util包Queue接口的基础上提供了pu ...
- 【Java线程】Lock、Condition
http://www.infoq.com/cn/articles/java-memory-model-5 深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...
- 【Java线程】锁机制:synchronized、Lock、Condition
http://www.infoq.com/cn/articles/java-memory-model-5 深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...
- 并发之lock的condition接口
13.死磕Java并发-----J.U.C之Condition 12.Condition使用总结 11.Java并发编程系列之十七:Condition接口 === 13.死磕Java并发-----J. ...
- Lock和Condition
1 什么是可重入锁 可重入锁是说一个线程在已经获取了该锁的情况下,还可以再次获取该锁. 主要的应用场景: 可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又 ...
- 【Java线程】锁机制:synchronized、Lock、Condition(转)
原文地址 1.synchronized 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility). 1.1 原子性 ...
随机推荐
- jquery实现文本框click清空文本内容
原先的样子 点击之后 如果没有输入内容则还原 否则为最新输入 实现代码 test.html <script src="https://code.jquery.com/jquery-3. ...
- IIS7 开发与 管理 编程 之 Microsoft.Web.Administration
一.引言: 关于IIS7 Mocrosoft.Web.Administration 网上这方面详细资料相对来说比较少,大家千篇一律的(都是一篇翻译过来的文章,msdn 里面的实列没有).前段做了一个 ...
- cocoapods使用-库托管到svn或者github
下拉svn库(自定义库或者第三方库)到工程中: 1. 若未安装,请安装cocoapods: http://www.cnblogs.com/sunjianfei/p/6089231.html ...
- 了解java虚拟机—在TALB上分配对象(10)
由于对象一般会分配在堆上,而堆是全局共享的.因此在同一时间,可能有多个线程在堆上申请空间.每次对象分内都必须要进行同步,因此TLAB这种线程专属的区域来避免多线程冲突.TLAB本身占用了eden区的空 ...
- 总结:JDK1.5-JDK1.8各个新特性
JDK1.5-JDK1.8各个新特性 JDK各个版本的新特性 要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言.以下介绍一下JDK1 ...
- Vim settings file on Windows
Question: I can't believe I am typing a question for a simple thing like this but here we are. I can ...
- canvas-arc.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 七牛云java(服务端)通用工具类
前言 需要安装lombok插件. 功能列表 上传本地文件 上传Base64图片 获取文件访问地址 上传MultipartFile 代码 pom.xml <dependency> <g ...
- (后端)excel设置日期格式的步骤
在excel中设置日期格式,分直接设置和代码设置. 一.直接设置: 选取日期所在的单元格,单元格右键菜单中--设置单元格格式.在单元格格式窗口中选数字类型为“日期”在右边的列表框中选取相应的日期格式即 ...
- VS发布web应用程序报:无法识别的特性“xmlns:xdt”。请注意特性名称区分大小写 或 未能将文件obj\...复制到obj\...未能找到路径
问题1:无法识别的特性“xmlns:xdt”.请注意特性名称区分大小写 问题2:未能将文件obj\...复制到obj\...未能找到路径 解决办法:将web项目文件下的obj文件夹从项目中排除,然后再 ...