老牛筋的英文翻译英语怎么说-快速学习催眠术
2023年4月5日发(作者:racquet club)
阻塞队列之LinkedBlockingQueue
概述
LinkedBlockingQueue内部由单链表实现,只能从head取元素,从tail添加元素。添加元素和获取元素都有独⽴的锁,也就是说
LinkedBlockingQueue是读写分离的,读写操作可以并⾏执⾏。LinkedBlockingQueue采⽤可重⼊锁(ReentrantLock)来保证在并发情况下的
线程安全。
构造器
LinkedBlockingQueue⼀共有三个构造器,分别是⽆参构造器、可以指定容量的构造器、可以穿⼊⼀个容器的构造器。如果在创建实例的时
候调⽤的是⽆参构造器,LinkedBlockingQueue的默认容量是_VALUE,这样做很可能会导致队列还没有满,但是内存却已经
满了的情况(内存溢出)。
1publicLinkedBlockingQueue();//设置容量为
2
3publicLinkedBlockingQueue(intcapacity);//设置指定容量
4
5publicLinkedBlockingQueue(Collection<?extendsE>c);//穿⼊⼀个容器,如果调⽤该构造器,容量默认也是_VALUE
LinkedBlockingQueue常⽤操作
取数据
take():⾸选。当队列为空时阻塞
poll():弹出队顶元素,队列为空时,返回空
peek():和poll烈性,返回队队顶元素,但顶元素不弹出。队列为空时返回null
remove(Objecto):移除某个元素,队列为空时抛出异常。成功移除返回true
添加数据
put():⾸选。队满是阻塞
offer():队满时返回false
判断队列是否为空
size()⽅法会遍历整个队列,时间复杂度为O(n),所以最好选⽤isEmtpy
put元素原理
基本过程:
1.判断元素是否为null,为null抛出异常
2.加锁(可中断锁)
3.判断队列长度是否到达容量,如果到达⼀直等待
4.如果没有队满,enqueue()在队尾加⼊元素
5.队列长度加1,此时如果队列还没有满,调⽤signal唤醒其他堵塞队列
1if(e==null)thrownewNullPointerException();
2
3intc=-1;
4Node
5finalReentrantLockputLock=k;
6finalAtomicIntegercount=;
terruptibly();
8try{
9while(()==capacity){
();
11}
12enqueue(node);
13c=Inc赞美桂花的句子唯美短句 rement();
14if(c+1
();
16}finally{
();
18}
take元素原理
基本过程:
1.加锁(依旧是ReentrantLock),注意这⾥的锁和写⼊是不同的两把锁
2.判断队列是否为空,如果为空就⼀直等待
3.通过dequeue⽅法取得数据
3.取⾛元素后队列是否为空,如果不为空唤醒其他等待中的队列
1publicEtake()throwsInterruptedException{
2Ex;
3intc=-1;
4finalAtomicIntegercount=;
5finalReentrantLocktakeLock=ck;
terruptibly();
7try{
8while(()==0){
();
10}
11x=dequeue();
12c=Decrement();
13if(c>1)
();
15}finally{
();
17}
18if(c==capacity)
19signalNotFull();
20returnx;
21}
enqueue()和dequeue()⽅法实现都⽐较简单,⽆⾮就是将元素添加到队尾,从队顶取⾛元素,感兴趣的朋友可以《从军行》的诗意 ⾃⼰去看⼀下,这⾥就不粘
贴了。
Link烧灼的拼音 edBlockingQueue与LinkedBlockingDeque⽐较
LinkedBlockingDeque和LinkedBlockingQueue的相同点在于:
1.基于链表
2.容量可选,不设置的话,就是Int的最⼤值
和LinkedBlockingQueue的不同点在于:
1.双端链表和单链表
2.不存在哨兵节点
3.⼀把锁+两个条件
实例:
⼩记:AtomicInteger的getAndIncrment和getAndDcrement()等⽅法,这些⽅法分为两步,get和increment(decrement),在get和increment
中间可能有其他线吹毛求疵什么意思 程进⼊,导致多个线程get到的数值是相同的,也会导致多个线程累加后的值其实累加1.在这种情况下,使⽤volatile也是
没有效果的,因为get之后没有对值进⾏修改,不能触发的效果。
1publicclassProduce难以言说的意思 rAndConsumer{
2publicstaticvoidmain(String[]args){
3
4try{
5Bloc全唐诗库 kingQueuequeue=newLinkedBlockingQueue(5);
6
7ExecutorServiceexecutor=edThreadPool(5);
8Produerproducer=newProduer(queue);
9for(inti=0;i<3;i++){
e(producer);
11}
e(newConsumer(queue));
13
wn();
15}catch(Exceptione){
tackTrace();
17}
18
19}
20}
21
22classProduerimplementsRunnable{
23
24privateBlockingQueuequeue;
25privateintnums=20;//循环次数
26
27//标记数据编号
28privatestaticvolatileAtomicIntegercount=newAtomicInteger();
29privatebooleanisRunning=true;
30publicProduer(){}
31
32publicProduer(BlockingQueuequeue){
=queue;
34}
35
36publicvoidrun(){
37Stringdata=null;
38try{
n(\"开始⽣产数据\");
n(\"-----------------------\");
41
42while(nums>0){
43nums--;
entAndGet();
45
(500);
n(tThread().getId()+\":⽣产者⽣产了⼀个数据\");
(Increment());
49}
50}catch(Exceptione){
tackTrace();
tTh抚今追昔的意思是什么 read().interrupt();
53}finally{
n(\"⽣产者线程退出!\");
55}
56}
57}
58
59classConsumerimplementsRunnable{
60
61privateBlockingQueuequeue;
62privateintnums=20;
63privatebooleanisRunning=true;
64
65publicConsumer(){}
66
67publicConsumer赞美祖国的优美句子 (BlockingQueuequeue){
=queue;
69}
70
71publicvoidrun(){
72
n(\"消费者开始消费\");
n(\"-------------------------\");
75
76while(nums>0){
77nums--;
78try{
79while(isRunning){
80intdata=(Integer)();
(500);
n(\"消费者消费的数据是\"+data);
83}
84
85}catch(Exceptione){
tackTrace();
tThread().interrupt();
88}finally{
n(\"消费者线程退出!\");
90}
91
92}
93}
94}
效果:
112:⽣产者⽣产了⼀个数据
211:⽣产者⽣产了⼀个数据
313:⽣产者⽣产了⼀个数圣僧 快不行 据
412:⽣产者⽣产了⼀个数据
5消费者消费的数据是-3
611:⽣产者⽣产了⼀个数据
713:⽣产者⽣产了⼀个数据
812:⽣产者⽣产了⼀个数据
9消费者消费的数据是-3
1013:⽣产者⽣产了⼀个数据
1111:⽣产者⽣产了⼀个数据
1212:⽣产者⽣产了⼀个数据
13消费者消费的数据是-3
1413:⽣产者⽣产了⼀个数据
1511:⽣产者⽣产了⼀个数据
16消费者消费的数据是-3
17消费者消费的数据是-3
可以看到,有多个producer在⽣产数据的时候get到的是相同的值。
更多推荐
blocking是什么意思cking在线翻译读音例
发布评论