移动端并发编程基础篇-阻塞队列ArrayBlockingQueue&LinkedBlockingQueue

本文详细解析了BlockingQueue与普通Queue的区别,对比了ArrayBlockingQueue与LinkedBlockingQueue的特点,并通过具体示例展示了队列满或空时的阻塞行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.BlockingQueue和普通Queue的区别

  BlockingQueue阻塞队列,多线程并发的上下文中,take,put,方法会发生阻塞状态

  Queue 普通的Queue如果实现生产者,消费者的阻塞等待,需要自己实现Blocking状态


2.ArrayBlockQueue&LinkedBlockQueue区别

  ArrayBlockQueue 数组阻塞队列,指定一个大小后无法扩容。put()方法中会检测如果添加的元素会超出数组范围,在put()方法地方会blocking住,一直到该queue可以添加元素

  LinkedBlockQueue 链表阻塞队列,不指定capacity可以无限制进行添加,put()方法不超过int.MaxVal不会发生阻塞

  相同点:

  数组阻塞队列和链表阻塞队列,queue队列为空的时候,再调用take方法会发生阻塞blocking状态


3.ArrayBlockQueue full阻塞队列满的情况下测试实例

 private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer>(8);

  for(int i = 0;i < 10;i++){
Thread thread = new Thread("threadName-" + i){
@Override
public void run() {
super.run();
int r = (int) (Math.random() * 100);
try {
System.out.println("tName-" + getName() + " putdata->" + r + " waiting...");
mQueue.put(r);
System.out.println("tName-" + getName() + " put succ -> " + r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}


try {
Thread.sleep(2*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}


Thread t = new Thread(){
@Override
public void run() {
super.run();
try {
Integer r = mQueue.take();
System.out.println("take data :" + r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();

发现倒数第二行打印地方,在take发生完毕后,被阻塞的66才会put成功

输出结果:

tName-threadName-0 putdata->83 waiting...
tName-threadName-3 putdata->12 waiting...
tName-threadName-2 putdata->27 waiting...
tName-threadName-2 put succ -> 27
tName-threadName-0 put succ -> 83
tName-threadName-6 putdata->9 waiting...
tName-threadName-6 put succ -> 9
tName-threadName-4 putdata->12 waiting...
tName-threadName-4 put succ -> 12
tName-threadName-8 putdata->2 waiting...
tName-threadName-8 put succ -> 2
tName-threadName-1 putdata->24 waiting...
tName-threadName-1 put succ -> 24
tName-threadName-9 putdata->65 waiting...
tName-threadName-9 put succ -> 65
tName-threadName-5 putdata->66 waiting...
tName-threadName-3 put succ -> 12
tName-threadName-7 putdata->82 waiting...
take data :27
tName-threadName-5 put succ -> 66



4.ArrayBlockQueue empty 阻塞队列空的情况下测试实例

private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer>(8);

//put the data into the queue
for(int i = 0;i < 6;i++){
try {
mQueue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

//
for(int i = 0;i < 12;i++){
Thread thread = new Thread("thread name-" + i){
@Override
public void run() {
super.run();
try {
System.out.println( getName() + " waiting for take...");
int r = mQueue.take();
System.out.println("tName-" + getName() + " take data->" + r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}


线程6,2,8一直都在阻塞waiting等待队列充数据才进行

输出结果:

thread name-0 waiting for take...
tName-thread name-0 take data->0
thread name-1 waiting for take...
thread name-11 waiting for take...
tName-thread name-11 take data->1
thread name-7 waiting for take...
thread name-9 waiting for take...
thread name-10 waiting for take...
tName-thread name-10 take data->5
thread name-4 waiting for take...
thread name-5 waiting for take...
thread name-3 waiting for take...
tName-thread name-9 take data->4
tName-thread name-1 take data->3
tName-thread name-7 take data->2
thread name-6 waiting for take...
thread name-2 waiting for take...
thread name-8 waiting for take...


5.LinkedBlockQueue full测试

  private BlockingQueue<Integer> mQueue = new LinkedBlockingQueue<Integer>();

  for(int i = 0;i < 100;i++){
Thread thread = new Thread("tName-" + i){
@Override
public void run() {
super.run();
int r = (int) (Math.random() * 50);
System.out.println("tName-" + getName() + " put " + r + " waiting for...");
try {
mQueue.put(r);
System.out.println("tName-" + " put " + r + " succ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}

  for计数规模可扩大到1000,10000,100000

  一旦new LinkedBlockingQueue<Integer>(capacity); 指定容量大小后和ArrayBlockingQueue效果一致

  

6.LinkedBlockQueue empty测试实例

   private BlockingQueue<Integer> mQueue = new LinkedBlockingQueue<Integer>();

   //put data
for(int i = 0;i < 6;i++){
try {
mQueue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

//take data
for(int i = 0;i < 8;i++){
Thread thread = new Thread("tName-" + i){
@Override
public void run() {
super.run();
try {
System.out.println("tName" + getName() + " take waiting...");
int r = mQueue.take();
System.out.println("tName" + getName() + " take r " + r + " succ");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}

输出结果可以看出,线程5和线程6一直block状态,没有发生take succ的行为。 添加6个元素,8个线程从队列获取元素。有两个线程会一直发生阻塞状态

输出结果:

tNametName-0 take waiting...
tNametName-3 take waiting...
tNametName-3 take r 1 succ
tNametName-2 take waiting...
tNametName-1 take waiting...
tNametName-1 take r 3 succ
tNametName-2 take r 2 succ
tNametName-4 take waiting...
tNametName-4 take r 4 succ
tNametName-0 take r 0 succ
tNametName-7 take waiting...
tNametName-6 take waiting...
tNametName-5 take waiting...
tNametName-7 take r 5 succ


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值