概述
生产者消费者问题是一个计算机领域的经典案例,计算机专业的同学在学习操作系统这门课时,一定会对此有所了解。下面就使用Java提供的多线程来实现这个案例。主要涉及到了线程间同步与线程间通信。
目前所学的创建多线程的常用方法包括:继承Thread类、实现Runnable接口(后续还有其他实现多线程的方法)
实现线程同步的常用方法包括:同步代码块、同步方法、锁Lock
实现线程间通信的常用方法包括:waiting()、notify()、notifyAll()
生产者与消费者模型
生产者负责生产产品,消费者负责消耗产品、产品的数量上限为20个,如果到达上限,则生产者应该停止生产,如果产品数量为0,则消费者应该停止消费。
实现代码
/**
* @author fredy feng
* @create 2020-08-15 19:16
*/
class Clerk{
private int productCount = 0;
//生产产品
public synchronized void produceProduct() {
if(productCount < 20){
productCount++;
System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount + "产品");
notify();
}
else {
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//消费产品
public synchronized void consumeProduct() {
if(productCount > 0){
System.out.println(Thread.currentThread().getName() + ":开始消费第" + productCount + "产品");
productCount--;
notify();
}
else{
//等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread{//生产者
private Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println(getName() + ":开始生产产品");
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produceProduct();
}
}
}
class Consumer extends Thread{//消费者
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println(getName() + ":开始消费产品");
while(true){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.consumeProduct();
}
}
}
public class ProductTest {
public static void main(String[] args) {
Clerk clerk = new Clerk();
Producer p1 = new Producer(clerk);
p1.setName("生产者1");
Consumer c1 = new Consumer(clerk);
c1.setName("消费者1");
Consumer c2 = new Consumer(clerk);
c2.setName("消费者2");
p1.start();
c1.start();
c2.start();
}
}