一、阻塞队列
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。
二、wait notify实现阻塞队列
public class BlockingQueueDemo {
//定义两把锁,只是简单的锁
private Object full = new Object();
private Object empty = new Object();
private int[] array;
private int head;
private int last;
private int size;
public BlockingQueueDemo(int maxSize) {
this.head = 0;
this.last = 0;
array = new int[maxSize];
}
public void put(int e) throws InterruptedException {
synchronized(full){
while (size == array.length) {//没有更多空间,需要阻塞
full.wait();
}
}
if (last < array.length) {
array[last] = e;
last++;
} else {
array[0] = e;
last = 1;
}
size++;
System.out.println(size+" :size大小,last: "+last+" :e: "+e);
//放入数据以后,就可以唤醒obj2对象的锁
synchronized(empty){
empty.notify();//达到了唤醒poll方法的条件
}
}
public int pool() throws InterruptedException {
synchronized(empty){
while (size == 0) {//没有数据,阻塞
empty.wait();
}
}
int returnValue = 0;
//队列中有数据,且head小于array的长度
returnValue = array[head];
array[head] = -1;
System.out.println(returnValue + " 弹出的"+"head:"+ head);
if (head < array.length) {//弹出head下标的数据
head++;
} else {
head = 0;
}
size--;
//拿走数据后,唤醒full对象锁
synchronized(full){
full.notify();
}
return returnValue;
}
public String toString(){
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
return "";
}
public static void main(String[] args) throws InterruptedException {
BlockingQueueDemo bq = new BlockingQueueDemo(5);
bq.put(10);
bq.put(20);
bq.put(30);
bq.put(40);
bq.put(50);
System.out.println();
bq.pool();
bq.pool();
bq.pool();
bq.pool();
System.out.println();
bq.toString();
System.out.println();
bq.put(100);
bq.put(200);
bq.put(300);
bq.put(400);
System.out.println();
bq.toString();
}
}
三、BlockingQueue
public class BlockingQueueDemo {
public static class Producer implements Runnable{
private final BlockingQueue<Integer> blockingQueue;
private volatile boolean flag;
private Random random;
public Producer(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
flag=false;
random=new Random();
}
public void run() {
while(!flag){
int info=random.nextInt(100);
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+" 生成了产品 "+info);
blockingQueue.put(info);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutDown(){
flag=true;
}
}
//消费者
public static class Consumer implements Runnable{
private final BlockingQueue<Integer> blockingQueue;
private volatile boolean flag;
public Consumer(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
}
public void run() {
while(!flag){
int info;
try {
System.out.println(Thread.currentThread().getName()+" 需要获得一个产品");
info = blockingQueue.take();
System.out.println(Thread.currentThread().getName()+" 消费了一个产品 "+info);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutDown(){
flag=true;
}
}
public static void main(String[] args) throws InterruptedException{
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(10);
Producer producer1=new Producer(blockingQueue);
Consumer consumer1=new Consumer(blockingQueue);
Consumer consumer2=new Consumer(blockingQueue);
Consumer consumer3=new Consumer(blockingQueue);
//线程池
ExecutorService service = Executors.newCachedThreadPool();
service.execute(consumer1);
service.execute(consumer2);
service.execute(consumer3);
service.execute(producer1);
//执行10S结束
Thread.sleep(10*1000);
consumer1.shutDown();
consumer2.shutDown();
consumer3.shutDown();
producer1.shutDown();
service.shutdown();
}
}