管程法是用于解决线程之间通信与线程不安全的一种解决办法,典型的生产者与消费者问题可以通过管程法进行解决,特点是建立一个消费者和生产者发生通信的缓冲区,进而实现解决线程通信。
实现:
- 生产者和消费者共享一片缓冲区,这里面可以存放产品,缓冲区的大小为10
- 生产者生产产品时,缓冲区内需要还有空间(缓冲区内存放产品数量小于10),才可以生产,生产完产品后通知消费者消费,如果没有空间则需要等待消费者消费,消费者消费后才能生产。
- 消费者消费产品时,缓冲区内需要有产品(缓冲区存放产品数量大于0),这样才能消费,否则需要等待生产者生产完产品后才能消费,消费者消费产品后需要通知生产者。
package com.tockm.thread;
public class TestWait {
public static void main(String[] args) {
SynContainer synContainer = new SynContainer();
new Producer(synContainer).start();
new Customer(synContainer).start();
}
}
class Producer extends Thread {
SynContainer container;
public Producer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.product(new Chicken(i));
System.out.println("生产了第"+i+"只鸡");
}
}
}
class Customer extends Thread {
SynContainer container;
public Customer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.consume();
System.out.println("消费了第"+container.consume().id+"只鸡");
}
}
}
class Chicken {
int id;
public Chicken(int id) {
this.id = id;
}
}
class SynContainer{
Chicken[] chickens = new Chicken[10];
int count = 0;
public synchronized void product(Chicken chicken){
System.out.println(chickens.length+"-"+count);
if (count == chickens.length){
// 通知消费者消费 生产等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
chickens[count] = chicken;
count++;
// 通知消费者消费
this.notifyAll();
}
public synchronized Chicken consume() {
while (count==0){
// 等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
Chicken chicken = chickens[count];
// 通知生产者生产
this.notifyAll();
return chicken;
}
}