基于LinkedBlocingQueue的生产者-消费者模式
class Test4{
static LinkedBlockingQueue<Integer> linkedBlockingDeque = new LinkedBlockingQueue<>();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(15);
for(int i = 0; i < 8; i++){
executorService.submit(new Product(linkedBlockingDeque));
}
for(int i = 0; i < 12; i++){
executorService.submit(new Customer(linkedBlockingDeque));
}
executorService.shutdown();
}
static class Product implements Runnable{
LinkedBlockingQueue<Integer> blockingQueue;
Product(LinkedBlockingQueue<Integer> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (true){
try {
int idx = new Random().nextInt();
blockingQueue.put(idx);
System.out.println(Thread.currentThread().getName() + "生产产品id:" + idx);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
static class Customer implements Runnable{
LinkedBlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();
Customer(LinkedBlockingQueue<Integer> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (true){
try {
int idx = blockingQueue.take();
System.out.println(Thread.currentThread().getName() + "消费产品id:" + idx);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
添加
- public void put(E e) throws InterruptedException{};
- public boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException{};
取出
- public E take() throws InterruptedException{};
- public E poll(long timeout, TimeUnit unit) throws InterruptedException{};
添加
put()
private final AtomicInteger count = new AtomicInteger();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
int c = -1;
Node<E> node = new Node<E>(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
}
signalNotEmpty()方法
private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
notEmpty.signal();
} finally {
takeLock.unlock();
}
}
取出
take()方法
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (count.get() == 0) {
notEmpty.await();
}
x = dequeue();
c = count.getAndDecrement();
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();
}
if (c == capacity)
signalNotFull();
return x;
}
signalNotEmpty()方法
private void signalNotFull() {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
notFull.signal();
} finally {
putLock.unlock();
}
}