public class TestProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer pd = new Producer(ss);
Consumer cs = new Consumer(ss);
new Thread(pd).start();
new Thread(pd).start();
new Thread(pd).start();
new Thread(cs).start();
new Thread(cs).start();
}
}
class SteamedBuns{
int id = 0;
SteamedBuns(int id){
this.id = id;
}
public String toString(){
return "SteamedBuns: " + id;
}
}
class Producer implements Runnable{
SyncStack sbsBuffer = null;
Producer(SyncStack sbsBuffer){
this.sbsBuffer = sbsBuffer;
}
public void run(){
for(int i = 0; i < 20; i++){
SteamedBuns sbs = new SteamedBuns(i);
sbsBuffer.putInto(sbs);
System.out.println("+++Produced+++ " + sbs);
try{
Thread.sleep(1000);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
SyncStack sbsBuffer = null;
Consumer(SyncStack sbsBuffer){
this.sbsBuffer = sbsBuffer;
}
public void run(){
for(int i = 0; i < 20; i++){
SteamedBuns sbs = sbsBuffer.takeOut();
System.out.println("--Consumed-- " + sbs);
try{
Thread.sleep(1000);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
}
class SyncStack{
int index = 0;
SteamedBuns[] arrSbs = new SteamedBuns[20];
public synchronized void putInto(SteamedBuns sbs){//線程鎖定與喚醒
while(index == arrSbs.length){
try{
this.wait();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
this.notifyAll();
arrSbs[index] = sbs;
index++;
}
public synchronized SteamedBuns takeOut(){//線程鎖定與喚醒
while(index == 0){
try{
this.wait();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
this.notifyAll();
index--;
return arrSbs[index];
}
}
當線程需要阻塞式的等待時,則調用wait()。而wait()的同時,鎖止權不由線程控制。
sleep()全程hold鎖止權。
wait()搭配notify()和notifyAll()使用。
能用Interface的Runnable就不用class的Thread