您的位置:首页 > 移动开发

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

2017-12-01 13:24 1111 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并发 移动 线程 编程
相关文章推荐