消费者生产者模式三种模式实现

本文通过三种不同实现方式对比分析了多线程环境下生产者消费者模式的应用,包括使用阻塞队列、锁机制及传统notify与wait方法,探讨了它们之间的区别与联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生产者和消费中模式在多线程中时经典中,我们下面通过这种方式来看看阻塞队列,锁机制以及最原始的方式的区别与联系:

[b][size=medium]对于通过阻塞队列:[/size][/b]

/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;

import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{

BlockingQueue<Product> queue;

public Consumer(BlockingQueue<Product> queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
System.out.println(Thread.currentThread().getName() + "is taking the product");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BlockingQueue<Product> queue;

public Producer(BlockingQueue<Product> queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.put(new Product());
System.out.println(Thread.currentThread().getName() + " is putting the product");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.blockingQueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BlockingQueue<Product> queue = new ArrayBlockingQueue<Product>(5);
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);

Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);

new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}




[b][size=medium]通过lock 锁机制[/size][/b]


/**
*
*/
package com.chihonglu.ConsumerProducer.lock;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author chihonglu
*
*/
public class BasketQueue {
private Lock lock = new ReentrantLock();

private Condition isEmpty = lock.newCondition();
private Condition isFull = lock.newCondition();
private int num = 0;
private List<Product> products = new LinkedList<Product>();

public void add(Product product) {
lock.lock();
try{
while(num == 10)
isFull.await();
num++;
products.add(product);
System.out.println("==========================");
System.out.println("the add string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
isEmpty.signal();
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}

public void take() {
lock.lock();
try {
while(num==0) {
isEmpty.await();
}
num--;
products.remove(num);
isFull.signal();
System.out.println("==========================");
System.out.println("the take string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
} catch (Exception e) {
// TODO: handle exception
} finally {
lock.unlock();
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.lock;

import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{

BasketQueue queue;

public Consumer(BasketQueue queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}


/**
*
*/
package com.chihonglu.ConsumerProducer.lock;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BasketQueue queue;

public Producer(BasketQueue queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.add(new Product());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.lock;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BasketQueue queue = new BasketQueue();
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);

Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);

new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}




[b][size=medium]通过notify 与wait方式[/size][/b]


/**
*
*/
package com.chihonglu.ConsumerProducer.general;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author chihonglu
*
*/
public class BasketQueue {

private int num = 0;
private List<Product> products = new LinkedList<Product>();

public void add(Product product) {
try{
while(num == 10)
wait();
num++;
products.add(product);
System.out.println("==========================");
System.out.println("the add string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
notifyAll();
}catch (Exception e) {
e.printStackTrace();
}
}

public void take() {
try {
while(num==0) {
wait();
}
num--;
products.remove(num);
notifyAll();
System.out.println("==========================");
System.out.println("the take string size is "+products.size());
System.out.println(Thread.currentThread().getName());
System.out.println("==========================");
} catch (Exception e) {
e.printStackTrace();
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.general;


/**
* @author chihonglu
*
*/
public class Consumer implements Runnable{

BasketQueue queue;

public Consumer(BasketQueue queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(1000 * 2);
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}


/**
*
*/
package com.chihonglu.ConsumerProducer.general;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
* @author chihonglu
*
*/
public class Producer implements Runnable{
private BasketQueue queue;

public Producer(BasketQueue queue) {
this.queue = queue;
}

@Override
public void run() {
while(true) {
try {
Thread.sleep(10*100);
queue.add(new Product());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}


/**
*
*/
package com.chihonglu.ConsumerProducer.general;


/**
* @author chihonglu
*
*/
public class Tester {
public static void main(String args[]) {
BasketQueue queue = new BasketQueue();
Consumer con1 = new Consumer(queue);
Consumer con2 = new Consumer(queue);

Producer producer1 = new Producer(queue);
Producer producer2 = new Producer(queue);

new Thread(con1).start();
new Thread(con2).start();
new Thread(producer1).start();
new Thread(producer2).start();
}
}




上面三种中,第一种其实就是第二种的封转, basketQueue其实就相当于一个阻塞队列,我们在arrayListBlockingQueue中已经lock锁机制已经进行了封装。

可以看java的源代码(put方法),如下:

public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final E[] items = this.items;
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == items.length)
notFull.await();
} catch (InterruptedException ie) {
notFull.signal(); // propagate to non-interrupted thread
throw ie;
}
insert(e);
} finally {
lock.unlock();
}
}


他在put方法中的实现第二种的实现原理是一样的。。所以阻塞队列实际就是对第二种basketQueue的封装。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值