關(guān)于生產(chǎn)者與消費(fèi)者之間的問題,其實(shí)在你準(zhǔn)確理解了線程的概念和方法的用法后,就很容易理解了。
以下是偶寫的一個(gè)關(guān)于生產(chǎn)者與消費(fèi)者的程序,看看對你理解有沒有幫助。
//生產(chǎn)者
class Producer implements Runnable{
private WOWOTou wwt=null;
private Basket bs=null;
private static int id=1;
private static boolean state=true;
Producer(Basket bs){
this.bs=bs;
}
public WOWOTou produce(){
try {
Thread.sleep( (long) (Math.random()*8000));
} catch (InterruptedException e) {
e.printStackTrace();
}
wwt=new WOWOTou(id);
//輸出調(diào)試語句
System.out.println();
System.out.println(Thread.currentThread().getName()+"生產(chǎn)了id為"+id+"的包子");
id++;
return wwt;
}
public void push(){
bs.push(wwt);
wwt=null;
}
public void run() {
while(state){
synchronized(this){
produce();
push();
}
}
}
}
//消費(fèi)者
class Custmer implements Runnable{
private Basket bs=null;
private WOWOTou wwt=null;
private static boolean state=true;
public Custmer(Basket bs) {
this.bs = bs;
}
public void cousme(){
try{
Thread.sleep((long) (Math.random()*8000));
}catch(InterruptedException e){
e.printStackTrace();
}
// 輸出調(diào)試語句
System.out.println();
System.out.println(Thread.currentThread().getName()+"消費(fèi)id為"+wwt.getWOWOTouID()+"的包子");
wwt=null;
}
public void pop(){
wwt=bs.pop();
}
public void run() {
while(state){
synchronized(this){
pop();
cousme();
}
}
}
}
//裝WOWOTou的Basket
class Basket{
private int index=0;
private final static int max=5;
private WOWOTou wwt=null;
private WOWOTou[] wwtbs=new WOWOTou[5];
private Producer p=null;
private static Basket bs=null;
private Basket(){}
public synchronized static Basket getBasket(){
if(bs==null)
bs=new Basket();
return bs;
}
public synchronized void push(WOWOTou wwt){
while(index==max){
System.out.println("包子滿了,趕緊吃包子");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
//輸出調(diào)試語句
System.out.println();
System.out.println("這是"+Thread.currentThread().getName()+"生產(chǎn)的id為"+wwt.getWOWOTouID()+"的包子");
wwtbs[index++]=wwt;
}
public synchronized WOWOTou pop(){
while(index==0){
System.out.println();
System.out.println("沒包子了,趕緊生產(chǎn)包子");
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notify();
if(index>0)
index--;
//輸出調(diào)試語句
System.out.println();
System.out.println(Thread.currentThread().getName()+"拿到id為"+wwtbs[index].getWOWOTouID()+"的包子");
return wwtbs[index];
}
}
class WOWOTou{
private int id=0;
WOWOTou(int id){
this.id=id;
}
public int getWOWOTouID(){
return id;
}
}
當(dāng)你明白線程后,就應(yīng)該考慮多線程和線程的性能問題,盡量減小鎖的粒度,但要注意死鎖問題。