阻塞队列 (生产者和消费者开发模式)
三种常用的阻塞队
ArrayBlockingQueue<T>;
LinkedBlockingQueue<T>;
SynchronousQueue<T>
// 在队列满时被阻塞
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<String>(19);
try {
arrayBlockingQueue.put("");
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果队列为空则阻塞
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<String>(19);
try {
arrayBlockingQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
使用阻塞队列
executorService = Executors.newSingleThreadExecutor();
TaskWithResult taskWithResult = new TaskWithResult();
Future<String> future = executorService.submit(taskWithResult);
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
final ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<String>(19);
try {
arrayBlockingQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
class TaskWithResult implements Callable<String> {
@Override
public String call() throws Exception {
//不等待就直接返回
String resu = arrayBlockingQueue.poll();
//正确的方法应该是,等待到有数据才继续
String resu = arrayBlockingQueue.take();
//防止列等
Stringresu=arrayBlockingQueue.poll(1,TimeUtil.DAY);
return resu;
}
}
// 实现一个简单的阻塞队列
class BlockingQ {
private Object noEmpty = new Object();
private Queue<Object> linkedList = new LinkedList<Object>();
public Object take() throws InterruptedException {
synchronized (noEmpty) {
if (linkedList.size() == 0) {
//要执行wait()操作,必须先得取得对象的锁
//执行wait()操作后,锁会释放
noEmpty.wait();
}
return linkedList.poll();
}
}
public void offer(Object object) {
synchronized (noEmpty) {
if (linkedList.size() == 0) {
//都必须取得对象的锁
noEmpty.notifyAll();
}
linkedList.add(object);
}
}
}
// 实现一个简单的阻塞队列2
class BlockingQ {
private Object noEmpty = new Object();
private Object noFull = new Object();
private Queue<Object> linkedList = new LinkedList<Object>();
private int maxLength = 10;
public Object take() throws InterruptedException {
synchronized (noEmpty) {
if (linkedList.size() == 0) {
noEmpty.wait();
}
synchronized (noFull) {
// 如果队列满
if (linkedList.size() == maxLength) {
linkedList.notifyAll();
}
return linkedList.poll();
}
}
}
public void offer(Object object) throws InterruptedException {
synchronized (noEmpty) {
if (linkedList.size() == 0) {
// 都必须取得对象的锁
noEmpty.notifyAll();
}
synchronized (noFull) {
// 如果队列满
if (linkedList.size() == maxLength) {
noFull.wait();
}
}
linkedList.add(object);
}
}
}
// 实现一个简单的阻塞队列3
class BlockingQ {
private Lock lock = new ReentrantLock();
// 一个锁可以创建多个condition
private Condition noEmpty = lock.newCondition();
private Condition noFull = lock.newCondition();
private Queue<Object> linkedList = new LinkedList<Object>();
private int maxLength = 10;
public Object take() throws InterruptedException {
lock.lock();
try {
if (linkedList.size() == 0) {
noEmpty.await();
}
// 如果队列满
if (linkedList.size() == maxLength) {
noFull.signalAll();
}
return linkedList.poll();
} finally {
lock.unlock();
}
}
public void offer(Object object) throws InterruptedException {
lock.lock();
try {
if (linkedList.size() == 0) {
//要执行signal都必须取得对象的锁
noEmpty.signalAll();
}
// 如果队列满
if (linkedList.size() == maxLength) {
noFull.await();
}
linkedList.add(object);
} finally {
lock.unlock();
}
}
}
注:如果未锁就直接执行await、signal、siganlAll 会抛异常