本文主要说下阻塞队列BlockQueue
队列是先进先出的,创建时可以固定大小,也可以不固定。
BlockQueue有很多实现,这里简单介绍ArrayBlockingQueue;
在增加时阻塞,和删除时为空,查看帮助文档
put() 阻塞住直到然后放入,take()
offer()返回false,poll()返回null
add()抛异常 ,remove()抛异常
上代码
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(3);
for (int i = 0; i < 2; i++) {
new Thread(() -> {
while (true) {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName() + "已经放了数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
new Thread(() -> {
while (true) {
try {
//将此处的睡眠时间分别改为100和1000,观察运行结果
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已经取走数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
这里给一个玩味例子,利用阻塞队列玩玩同步通知
public class BlockingQueueCommunication {
/**
* @param args
*/
public static void main(String[] args) {
final Business business = new Business();
new Thread(
() -> {
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sub(int i){
try {
queue1.put(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void main(int i){
try {
queue2.put(1);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
队列put时阻塞了,只有等到take()的时候,才能继续put(),这样线程间就有一个通信了。蛮有意思。
JDK1.8中的阻塞队列实现共有7个,分别是ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue、LinkedTransferQueue以及LinkedBlockingDeque,下面资料对他们进行一个简单的分析。转自此处;里面总结的还可以,我们自己也可以看手册和源码嘛。有时间再总结,先睡觉了。