ArrayBlockingQueue:基于数组实现,使用一把锁,2个信号量,一个数组,一个放数据index,一个取数据index,存放数据时,每次放完数据就会通知取阻塞的取线程,每次取完数据就会通知阻塞的放线程,请注意:取和放是互斥的。
LinkedBlockingQueue:基于单链表实现,使用2把锁,每一把锁一个信号量,一个node链表,一个指向放数据的node节点last,一个指向取数据的node节点head,存放数据时,每次放完数据,若容器未满,会继续通知放线程,放数据,直到容器放满,每次取数据时,取完数据,若容器还有数据,都会通知取线程继续取数据,直到容器内数据为空,请注意:取和取是互斥的,放和放是互斥的,取和放可以同时进行。
代码测试,可以在debug模式下,查看数据存取的过程
package test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
// 对比阻塞队列的不同点
public class Container {
public static void main(String\[\] args) {
ThreadPoolExecutor tp = new ThreadPoolExecutor(5, 10, 50l,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10));
Container container = new Container();
final ArrayBlockingQueue<Integer> a = new ArrayBlockingQueue<Integer>(
10);
final LinkedBlockingQueue<Integer> l = new LinkedBlockingQueue<Integer>(
10);
producer p = container.new producer(l);
consumer c = container.new consumer(l);
tp.submit(p);
tp.submit(c);
}
/*
\* static class source { static int\[\] a = new int\[10\]; static int take;
\* static int put; static int count; final static ReentrantLock lock = new
\* ReentrantLock(); final static Condition notFull = lock.newCondition();
\* final static Condition notEmpty = lock.newCondition(); static void
\* put(int i) { lock.lock(); try{ if (count == 10) { try { notEmpty.await();
*
\* } catch (InterruptedException e) { // TODO Auto-generated catch block
\* e.printStackTrace(); }
*
\* } a\[put\] = i; System.out.println(a); put++; count++; if (put >= 10) { put
\* = 0; } notFull.signal(); }finally{ lock.unlock(); }
*
\* }
*
\* static synchronized int get() { lock.lock(); try { int tar; if (count ==
\* 0) { try { notFull.await(); } catch (InterruptedException e) { // TODO
\* Auto-generated catch block e.printStackTrace(); } } tar = a\[take\];
\* take++; count--; if (take >= 10) { take = 0; } notEmpty.signal();
\* System.out.println(a.toString()); return tar; }finally{ lock.unlock(); }
\* }
*
\* public static void set(int i) { put(i);
*
\* }
*
\* }
*/
//生产者线程
class producer implements Runnable {
BlockingQueue<Integer> a;
public producer(BlockingQueue a) {
this.a = a;
}
@Override
public void run() {
try {
doRun();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doRun() throws InterruptedException {
int i = 0;
for (;;) {
// Thread.currentThread().sleep(1000);
a.put(i++);
}
}
}
//消费者线程
class consumer implements Runnable {
BlockingQueue<Integer> a;
public consumer(BlockingQueue a) {
this.a = a;
}
@Override
public void run() {
try {
doRun();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void doRun() throws InterruptedException {
for (;;) {
try {
/*
\* System.out.println(a.toString());
\* System.out.println(a.take());
*/
a.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}