法1管程法:
图11-17 生产者消费者示意图
产品
class Chicken{
int id;
public Chicken(int id) {
this.id = id;
}
}
缓冲区(装产品)
class Container{
//定义装鸡的篮子大小
Chicken[] chickens =new Chicken[10];
int count=0;
//生产者生产鸡
public synchronized void push(Chicken chicken){
//如果篮子满了,则生产者停止生产
//如果篮子没满,生产鸡
//通知消费者可以开始消费了
}
//消费者消费鸡
public synchronized Chicken pop(){
//如果篮子中没有鸡,则消费者停止消费
//如果篮子中有鸡,消费鸡
//通知生产者开始生产
}
生产方法 push()
public synchronized void push(Chicken chicken){
//如果篮子满了,则生产者停止生产
if (count==chickens.length){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//如果篮子没满,生产鸡
chickens[count]=chicken;
count++;
//通知消费者可以开始消费了
this.notifyAll();
}
消费方法 pop()
public synchronized Chicken pop(){
//如果篮子中没有鸡,则消费者停止消费
if (count==0){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//如果篮子中有鸡,消费鸡
count--;
Chicken chicken =chickens[count];
//一定要先count--,因为生产者先把chicken放到chickens[count]里,再count++,所以count--才能得到放入的chicken
//通知生产者开始生产
this.notifyAll();
return chicken;
}
生产者
class Productor extends Thread{
Container container;
public Productor(Container container){
this.container=container;
}
@Override
public void run() {
for (int i = 0; i <30 ; i++) {
container.push(new Chicken(i));
System.out.println("生产共"+i+"只鸡");
}
}
}
消费者
class Consumer extends Thread{
Container container;
public Consumer(Container container){
this.container=container;
}
@Override
public void run() {
for (int i = 0; i <30 ; i++) {
// Chicken chicken = container.pop();
// 这么写中间操作系统可能进行线程的上下文切换,导致显示未生产先消费
// System.out.println("消费了第" + chicken.id + "只鸡");
System.out.println("消费了第" + container.pop().id+ "只鸡");
}
}
}
main方法
public class TestPC {
public static void main(String[] args) {
Container container = new Container();
Productor productor = new Productor(container);
Consumer consumer = new Consumer(container);
productor.start();
consumer.start();
}
}
法2信号灯法:
//信号灯法
public class TestPC2 {
public static void main(String[] args) {
TV tv =new TV();
new Actor(tv).start();
new Audience(tv).start();
}
}
//生产者->演员
class Actor extends Thread{
TV tv;
public Actor(TV tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i%2==0){
tv.play("非人哉动画");
}else{
tv.play("我是渣渣辉广告");
}
}
}
}
//消费者->观众
class Audience extends Thread{
TV tv;
public Audience(TV tv){
this.tv=tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
class TV{
//产品->节目
String show;
boolean flag=true;
//true演员表演节目,观众等待.flase演员等待,观众观看
//表演节目
public synchronized void play(String show){
if (!flag){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
this.show = show;
System.out.println("演员表演了"+show);
this.flag = !this.flag;
//通知观众观看
this.notifyAll();
}
//观看
public synchronized void watch(){
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("观众观看了-->"+show);
this.flag = !this.flag;
//通知演员表演
this.notifyAll();
}
}