可阻塞的队列
一.概述:
1.队列包含固定长度的队列和不固定长度的队列。
2.什么是可阻塞队列,阻塞队列的作用与实际应用,阻塞队列的实现原理。
3.ArrayBlockingQueue:
(1)看BlockingQueue类的帮助文档,其中有各个方法的区别对比的表格。
(2)只有put方法和take方法才具有阻塞功能
4.用3个空间的队列来演示阻塞队列的功能和效果。
5.用两个具有1个空间的队列来实现同步通知功能。
6.阻塞队列与Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是由同一方设置和释放信号量。
1、阻塞队列的原理:用到了Lock锁,俩个Condition
查看jdk api,Condition对象的解释,有阻塞队列原理的实现方式
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
2、通过阻塞队列 BlockingQueue的阻塞机制的数据存取,来达到Lock的锁机制
public class BlockingQueueCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=1;i<=50;i++){
business.sub(i);
}
}
}
).start();
for(int i=1;i<=50;i++){
business.main(i);
}
}
static class Business {
BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
{
Collections.synchronizedMap(null);
try {
System.out.println("xxxxxdfsdsafdsa");
queue2.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void sub(int i){
try {
queue1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int j=1;j<=10;j++){
System.out.println("sub thread sequece of " + j + ",loop of " + i);
}
try {
queue2.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void main(int i){
try {
queue2.put(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int j=1;j<=100;j++){
System.out.println("main thread sequece of " + j + ",loop of " + i);
}
try {
queue1.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}