import java.util.Vector;
public class SyncTest {
public static void main(String[] args){
SyncTest t = new SyncTest();
final SyncTest.SyncStack ss = t.new SyncStack();
Runnable Producer = new Runnable() {
private char c = 'a';
public void run() {
try {
while(c != 'j') {
Thread.sleep(500); //生产时间间隔
System.out.println("produce=" + c);
ss.push(c++);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable Consumer = new Runnable() {
public void run() {
int i = 9;
try {
while(i-- > 0) {
Thread.sleep(1000); //消费时间间隔
System.out.println("consume=" + ss.pop());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(Producer).start();
new Thread(Consumer).start();
}
/**
* 一个栈,相当于商店,
* 总是把最先生产的商品消费掉。
*/
class SyncStack {
private Vector<Character> stack;
public SyncStack() {
stack = new Vector<Character>(100); //可容纳100件商品
}
public synchronized void push(char c) {
stack.add(c);
//一旦线程被释放并可随后再次获得栈的锁,
//该线程就可以继续执行pop()完成从栈缓冲区中移走字符任务的代码。
//对this.notify()的调用将释放一个因栈空而调用wait()的单个线程。
//在共享数据发生真正的改变之前调用notify()不会产生任何结果。
//只有退出该synchronized块后,才会释放对象的锁,所以当栈数据在被改变时,正在等待锁的线程不会获得这个锁。
this.notify();
}
public synchronized char pop() {
char c;
while(stack.size() == 0) {
try {
//wait()方法在对栈的共享数据作修改之前被调用。
//这是非常关键的一点,因为在对象锁被释放和线程继续执行改变栈数据的代码之前,数据必须保持一致的状态。
//必须使所设计的代码满足这样的假设:在进入影响数据的代码时,共享数据是处于一致的状态。
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
c = stack.remove(stack.size() - 1);
return c;
}
}
}
/**
* 一个空的盒子,一次只能把一个物品放进去,一次也只能拿出一个盒子
*/
public class TestGoodsBox {
public static void main(String[] args) {
final GoodsBox box = new GoodsBox();
Runnable a = new Runnable() {
public void run() {
int i = 10;
try {
while(i-- > 0) {
Thread.sleep(500);
String goods = "goods-" + i;
System.out.println(Thread.currentThread().getName() + "put in " + goods);
box.putIn(goods);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable b = new Runnable() {
public void run() {
int i = 10;
while(i-- > 0) {
Object goods = box.takeOut();
System.out.println(Thread.currentThread().getName() + "took out " + goods);
}
}
};
new Thread(a).start();
new Thread(b).start();
}
}
/**
* 物品盒子类
*/
class GoodsBox {
private Object o;
public C() {
this.o = null; //null表示盒子为空
}
public synchronized void putIn(Object goods) {
while(this.o != null) {
try {
this.wait(); //盒子被占用处于等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.o = goods; //放入物品
this.notify(); //通知盒子为满
}
public synchronized Object takeOut() {
while(o == null) {
try {
this.wait(); //盒子为空时等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object goods = this.o;
this.o = null; //取出物品
this.notify(); //通知盒子为空
return goods;
}
}