学习多线程的过程中用代码实现的BlockingQueue队列。
阻塞队列实现类。
package com.xtli.controller.thread;
import java.util.LinkedList;
public class BlockingQueueTest {
LinkedList<String> BQList = new LinkedList<String>();
private int size = 0;//队列大小
private int count = 0;//队列计数器
private Object obj = new Object();//同步对象
public BlockingQueueTest(int size) {
this.size = size;
}
public void inQueue(String str) {
synchronized(obj) {
System.out.println("线程"+Thread.currentThread().getName()+":"+str+"准备进入队列。。");
if(this.size == count) {
try {
System.out.println("线程"+Thread.currentThread().getName()+":"+"队列已满,阻塞。。");
obj.wait();//等待其他线程从队列中取值
} catch (InterruptedException e) {
e.printStackTrace();
}
}
BQList.add(str);
count++;
System.out.println("线程"+Thread.currentThread().getName()+":"+str+"成功进入队列。。");
System.out.println("当前队列中的值为:"+BQList.toString());
obj.notifyAll();//通知等待的其他线程
}
}
public String outQueue() {
synchronized(obj) {
System.out.println("线程"+Thread.currentThread().getName()+":"+"准备从队列中取值。。");
if(this.count == 0) {
try {
System.out.println("线程"+Thread.currentThread().getName()+":"+"队列已空,阻塞。。");
obj.wait();//等待其他线程,往队列里塞值
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
String str = BQList.pollFirst();
System.out.println("线程"+Thread.currentThread().getName()+":"+str+"成功出队列。。");
System.out.println("当前队列中的值为:"+BQList.toString());
obj.notifyAll();//通知等待的其他线程
return str;
}
}
}
启用两个线程,一个线程向队列中塞值,另外一个从队列中取值。
package com.xtli.controller.thread;
public class BlockingQueueMain {
static BlockingQueueTest BQ = new BlockingQueueTest(3);
static class BlockingQueueInQueue extends Thread {
public void run() {
for(int i=0;i<5;i++) {//向队列中塞了5个值
BQ.inQueue(String.valueOf(i));
}
}
}
static class BlockingQueueOutQueue extends Thread {
public void run() {
for(int i=0;i<6;i++) {//从队列中取了6个值
BQ.outQueue();
}
}
}
public static void main(String[] args) throws InterruptedException {
/*final BlockingQueueTest BQ = new BlockingQueueTest(3);
BQ.inQueue("1");
BQ.inQueue("2");
BQ.inQueue("3");
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
BQ.inQueue("4");
BQ.inQueue("5");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
String str1 = BQ.outQueue();
System.out.println(str1);
String str2 = BQ.outQueue();
System.out.println(str2);
}
});
t1.start();
Thread.sleep(1000);
t2.start();*/
new BlockingQueueInQueue().start();
new BlockingQueueOutQueue().start();
}
}
在BlockingQueueMain中,BlockingQueueInQueue向队列中塞了5次值,而BlockingQueueOutQueue从队列中取了6次,前5次均能正常取出,当第6次再次取值时,因为此时队列已空,此线程会一直处于等待状态。
BlockingQueueOutQueue如果循环5次从队列中取值,如下
BlockingQueueInQueue如果循环6次,BlockingQueueOutQueue循环5次,结果如下。