为什么要有生产者与消费者模式
- 为了解决生产者和消费者速度不匹配的问题,如果生产者的速度大于消费者的速度,则生产者要等待消费者处理完生产者才能产生新的数据。
生产者与消费者模式有两种
实现生产者与消费者模式有二种实现方式
- wait和notify方式
- ReentrantLock的condition方式
代码示例
- 示例实现的是多生产者与多消费者模式,采用的是ReentrantLock的condition方式
- 特殊情况:按照上述一生产与一消费的情况,通过创建多个生产者和消费者线程,实现多生产与多消费的情况,将会出现“假死”。
- 具体原因:多个生产者和消费者线程。当全部运行后,生产者线程生产数据后,可能唤醒的同类即生产者线程。此时可能会出现如下情况:所有生产者线程进入等待状态,然后消费者线程消费完数据后,再次唤醒的还是消费者线程,直至所有消费者线程都进入等待状态,此时将进入“假死”。
- 解决方法:将notify()或signal()方法改为notifyAll()或signalAll()方法,这样就不怕因为唤醒同类而进入“假死”状态了。
/**
* 生产者
*
* @author jiangxinlin
* @version 2018-06-12
*/
public class Producer {
private Lock lock;
private Condition condition;
public Producer(Lock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
public void setValue() {
try {
lock.lock();
System.out.println(Thread.currentThread().getId() + "》》》进入生产者");
while (StringObject.list != null && StringObject.list.size() >= 10) {
condition.await();
}
String value = System.currentTimeMillis() + "" + System.nanoTime();
System.out.println(Thread.currentThread().getId() + "---生产的值是:" + value);
StringObject.list.add(value);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 消费者
*
* @author jiangxinlin
* @version 2018-06-12
*/
public class Consumer {
private Lock lock;
private Condition condition;
public Consumer(Lock lock, Condition condition) {
super();
this.lock = lock;
this.condition = condition;
}
public void getValue() {
try {
lock.lock();
System.out.println(Thread.currentThread().getId() + "》》》进入消费者");
while (StringObject.list != null && StringObject.list.size() == 0) {
condition.await();
}
String value = StringObject.list.get(StringObject.list.size() - 1);
System.out.println(Thread.currentThread().getId() + "---消费的值是:" + value);
StringObject.list.remove(value);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
Condition newCondition = lock.newCondition();
Producer product = new Producer(lock, newCondition);
Consumer consumer = new Consumer(lock, newCondition);
for (int i = 0; i < 3; i++) {
ThreadProducer pThread = new ThreadProducer(product);
ThreadConsumer cThread = new ThreadConsumer(consumer);
pThread.start();
cThread.start();
}
}
}
/**
* 生产者线程
* @author jiangxinlin
* @version 2018-06-12
*/
public class ThreadProducer extends Thread {
private Producer producer;
public ThreadProducer(Producer producer) {
this.producer = producer;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
producer.setValue();
}
}
}
/**
* 消费者线程
* @author jiangxinlin
* @version 2018-06-12
*/
public class ThreadConsumer extends Thread {
private Consumer consumer;
public ThreadConsumer(Consumer consumer) {
this.consumer = consumer;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
consumer.getValue();
}
}
}
/**
* 生产者与消费者操作的公共变量
* @author jiangxinlin
* @version 2018-06-12
*/
public class StringObject {
public static List<String> list = new ArrayList<>();
}