import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class 管程法 {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container, "one").start();
new Consumer(container, "two").start();
}
}
//生产者,将数据存入临界资源
class Productor extends Thread {
int j = 0;
SynContainer container;
public Productor(SynContainer container) {
this.container = container;
}
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Data(j));
System.out.println("生产第" + (j) + "个馒头");
j++;
}
}
}
//消费者,将数据从临界资源中取出
class Consumer extends Thread {
SynContainer container;
String a;
public Consumer(SynContainer container, String a) {
this.container = container;
this.a = a;
}
public void run() {
for (int i = 1; i < 100; i++) {
Data b=container.pop();
System.out.println("消费者" + a + "消费第" + (b.i) + "个馒头");
}
}
}
//管程
class SynContainer {
final Lock lock = new ReentrantLock();
final Condition condition1 = lock.newCondition();
final Condition condition2 = lock.newCondition();
private Data[] datas = new Data[10]; // 临界资源
private int count =0;// 计数器
//存
public void push(Data data) {
lock.lock();//取得锁
// 临界资源存满时阻塞
if (count == datas.length) {
try {
condition1.await();// 线程阻塞(用await不能用wait,否则会报错),阻塞时释放锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
datas[count] = data;
count++;
condition2.signalAll(); // 存在数据,通知消费者可消费
lock.unlock();//释放锁
}
//取
public synchronized Data pop() {
lock.lock();
// 临界资源中无数据时阻塞
if (count<=0) {
try {
condition2.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Data a=datas[count-1];
datas[count-1]=null;
count--;
condition1.signalAll();// 存在空间,通知生产者可生产
lock.unlock();//释放锁
return a;
}
}
//产品
class Data {
int i;
public Data( int i) {
this.i = i;
}
}