两个东西,看名字就知道是先进先出的队列,不过这个blocking是什么意思,很显然这是“块”的意思,也就是这是一个阻塞队列。
举个生活中的例子,篮子里面最多只能放5个苹果,一个人往篮子里面放,一个人往篮子里面拿,假设篮子的容量满了,就要等一个人拿出来之后才能放,篮子空了也要等一个人把苹果放进去才能拿。
上面的例子有点消费生产者模式的意思。
跟今天我们要说的BlockingQueue有啥关系呢,这两个BlockingQueue就好像这个篮子一样。满了就等有容量的时候再装,空了就等有东西的时候再拿。
唯一的区别就是,ArrayBlockingQueue的内部是数组,LinkedBlockingQueue的内部是链表。
拿ArrayBlockingQueue举例子。
如果写出了下面的代码,就完了。
BlockingQueue<String> a = new ArrayBlockingQueue<String>(5);
for (int i = 0; i < 10; i++) {
try {
a.put(i + "");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("111");
因为永远执行不到最后面的打印语句,会永远卡在那里,容量只有5,但是要放10个东西。
我们可以这样做:
BlockingQueue<String> a = new ArrayBlockingQueue<String>(5);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
a.put(i + "");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
String str;
try {
while ((str = a.take()) != null) {
System.out.println("take : " + str);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
写两个线程,一个放一个拿,这样就不会阻塞了,阻塞的好处就是,可以在一定程度上节约空间。
我们可以在这些队列中存放线程哦,假设有10个任务,5个线程,把任务丢进去,让5个线程去执行,哪个线程执行完了就去执行下一个任务,任务也可以用队列保存起来,这样也不会弄混。
good idea!