移动端并发编程基础篇-阻塞队列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
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
相关文章推荐
- JAVA并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue
- 深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue
- Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)
- 并发队列ConcurrentLinkedQueue和阻塞栈LinkedBlockingQueue用法和阻塞队列ArrayBlockingQueue
- [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
- Java常用的2种阻塞队列ArrayBlockingQueue和LinkedBlockingQueue
- Java阻塞队列ArrayBlockingQueue和LinkedBlockingQueue实现原理分析
- Java阻塞队列ArrayBlockingQueue和LinkedBlockingQueue实现原理分析
- Java并发编程与技术内幕:ArrayBlockingQueue、LinkedBlockingQueue及SynchronousQueue源码解析
- Java阻塞队列ArrayBlockingQueue和LinkedBlockingQueue实现原理分析(还没看,先马)
- java点滴之阻塞队列:PriorityBlockingQueue,SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue
- JDK源码分析之主要阻塞队列实现类ArrayBlockingQueue -- java消息队列/java并发编程/阻塞队列
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
- 并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
- Java多线程与并发应用-(10)-java阻塞队列实现ArrayBlockingQueue
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
- 并发队列ConcurrentLinkedQueue与阻塞队列LinkedBlockingQueue的区别
- 并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
- ConcurrentLinkedQueue并发队列和LinkedBlockingQueue阻塞队列的详细用法和示例