老牛筋的英文翻译英语怎么说-快速学习催眠术


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;

4Nodenode=newNode(e);

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在线翻译读音例