BlockingQueue,队列对于很多人来说非常陌生.queue就是队列,BlockingQueue支持阻塞的机制,阻塞的放入数据和阻塞的得到数据.我们直接实现一个LinkedBlockingQueue 有序有界阻塞队列,上代码.再分析~~
public class Myqueue {
private final LinkedList list = new LinkedList<>();
private final AtomicInteger count = new AtomicInteger(0);
private final int minSize = 0;
private final int maxSize;
public Myqueue(int size) {
this.maxSize = size;
}
private final Object object = new Object();
public String take() {
String string = null;
synchronized (object) {
while (count.get() == minSize) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
string = list.removeFirst();
count.decrementAndGet();
object.notify();
return string;
}
}
public void put(String str) {
synchronized (object) {
while (count.get() == maxSize) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(str);
count.incrementAndGet();
object.notify();
System.out.println("新加入的元素为:" + str);
}
}
public static void main(String[] args) {
final Myqueue myqueue = new Myqueue(5);
myqueue.put("a");
myqueue.put("b");
myqueue.put("c");
myqueue.put("d");
myqueue.put("e");
Thread thread1 = new Thread(new Runnable() {
public void run() {
myqueue.put("f");
myqueue.put("g");
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
public void run() {
String string1 = myqueue.take();
System.out.println("获得的元素为-->" + string1);
String string2 = myqueue.take();
System.out.println("获得的元素为-->" + string2);
}
});
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread2.start();
}
}
不要被代码给吓到,其实一点一点分析一点都不难.首先我们直接看定义的东西.
表示的是定义一个有序的数组.↓↓↓↓↓↓↓
private final LinkedList list = new LinkedList<>();
利用AtomicInteger来实现原子性的递增递减操作.↓↓↓↓↓↓↓
private final AtomicInteger count = new AtomicInteger(0);
数据能接受的最小长度.↓↓↓↓↓↓↓
private final int minSize = 0;
数组能接受的最大长度,通过构造方法传入,毕竟要有界啊~↓↓↓↓↓↓↓
private final int maxSize;
利用 synchronized 的对象锁.↓↓↓↓↓↓↓
private final Object object = new Object();
定义的东西看完了,先不看代码,上分析图(文字版)~
(put)----> (0,0,0,0,0)----->(take)
看上面的小图.
put:如果容器中没有存到5个元素(也就是容器最大值),那么我正常put操作,如果我的容器已经存在5个元素,那么想再往里添加元素也就是put操作,肯定是添加不进去的,所以必须得阻塞着,等到容器中的元素被拿走.
take:如果容器中存在元素,那么我就take操作,取出元素.如果容器中的元素已经没有了,那么take就得阻塞着,等待着容器中有数据,也就是put操作.
上面的情况真的结束了吗?考虑一种极端的.容器中如果已经满了,想put操作肯定是不可以的,但是想put肯定要通知(notify())take.告诉take:啊你可以拿元素了....是吧 反之,如果容器中没有数据了,take也必须告诉(notify())put:哦你也可以放元素了
然后我们再看上面的代码,结合场景,自悟~~~~~
打印结果放上~
新加入的元素为:a
新加入的元素为:b
新加入的元素为:c
新加入的元素为:d
新加入的元素为:e
获得的元素为-->a
新加入的元素为:f
获得的元素为-->b
新加入的元素为:g
有啥不懂的请加qq727865942,微信号 cto_zej,觉得是干货请打赏~~~~~~~~~~