1.生產(chǎn)者-消費(fèi)者模式實(shí)現(xiàn)概述
生產(chǎn)者與消費(fèi)者模式是我們?cè)诰幊踢^(guò)程中經(jīng)常會(huì)遇到的,就像我們生活那樣,生產(chǎn)者生產(chǎn)出產(chǎn)品,消費(fèi)者去購(gòu)買(mǎi)產(chǎn)品。在這里我們創(chuàng)建三個(gè)線程,一個(gè)主控線程main,用于創(chuàng)建各輔助線程;一個(gè)生產(chǎn)者線程,用于生產(chǎn)產(chǎn)品;一個(gè)消費(fèi)者線程,用于購(gòu)買(mǎi)產(chǎn)品。另外,我們創(chuàng)建一個(gè)隊(duì)列類Queue,生產(chǎn)線程生產(chǎn)的產(chǎn)品將放置到該隊(duì)列中,然后消費(fèi)者線程在該隊(duì)列中取走產(chǎn)品。
2.實(shí)現(xiàn)該模式的要點(diǎn):
首先必須讓生產(chǎn)者線程與消費(fèi)者線程達(dá)到同步,也就是說(shuō),當(dāng)生產(chǎn)者線程生產(chǎn)出產(chǎn)品后,消費(fèi)者才能去取,依此輪回。當(dāng)生產(chǎn)者線程放置產(chǎn)品到隊(duì)列中時(shí),隊(duì)列要檢查隊(duì)列是否已滿,如已滿,則等待消費(fèi)者線程將產(chǎn)品取走,否則放置產(chǎn)品到隊(duì)列中。當(dāng)消費(fèi)者線程在隊(duì)列中取產(chǎn)品時(shí),隊(duì)列也要檢查隊(duì)列是否為空,如果為空,則等待生產(chǎn)者線程放置產(chǎn)品到隊(duì)列,否則在隊(duì)列中取走產(chǎn)品。
3.源代碼:
class MainThread
{
public static void main(String[] args)
{
Queue queue=new Queue();
Producer producer=new Producer(queue);
Consumer consumer=new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();
}
}
/*注意:wait notify notifyAll只能在同步方法或內(nèi)步塊中調(diào)用*/
class Queue
{
int product=0;
boolean bfull=false;
public synchronized void setProduct(int product)
{
if(bfull)//如果隊(duì)列已滿,則調(diào)用wait等待消費(fèi)者取走產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開(kāi)始放置產(chǎn)品到隊(duì)列中*/
this.product=product;
System.out.println("Producer set product:"+product);
bfull=true;
notify();//生產(chǎn)產(chǎn)品后通知消費(fèi)者取走產(chǎn)品
}
public synchronized void getProduct()
{
if(!bfull)//如果隊(duì)列是空的,則調(diào)用wait等待生產(chǎn)者生產(chǎn)產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開(kāi)始從隊(duì)列取走產(chǎn)品*/
System.out.println("Consumer get product:"+product);
bfull=false;
notify();//取走產(chǎn)品后通知生產(chǎn)者繼續(xù)生產(chǎn)產(chǎn)品
}
}
class Producer implements Runnable
{
Queue queue;
Producer(Queue queue)
{
this.queue=queue;
}
public void run()//生產(chǎn)線程
{
for(int i=1;i<=10;i++)
{
queue.setProduct(i);
}
}
}
class Consumer implements Runnable
{
Queue queue;
Consumer(Queue queue)
{
this.queue=queue;
}
public void run()//消費(fèi)線程
{
for(int i=1;i<=10;i++)
{
queue.getProduct();
}
}
}
輸出結(jié)果如下:
Producer set product:1
Consumer get product:1
Producer set product:2
Consumer get product:2
Producer set product:3
Consumer get product:3
Producer set product:4
Consumer get product:4
Producer set product:5
Consumer get product:5
Producer set product:6
Consumer get product:6
Producer set product:7
Consumer get product:7
Producer set product:8
Consumer get product:8
Producer set product:9
Consumer get product:9
Producer set product:10
Consumer get product:10
生產(chǎn)者與消費(fèi)者模式是我們?cè)诰幊踢^(guò)程中經(jīng)常會(huì)遇到的,就像我們生活那樣,生產(chǎn)者生產(chǎn)出產(chǎn)品,消費(fèi)者去購(gòu)買(mǎi)產(chǎn)品。在這里我們創(chuàng)建三個(gè)線程,一個(gè)主控線程main,用于創(chuàng)建各輔助線程;一個(gè)生產(chǎn)者線程,用于生產(chǎn)產(chǎn)品;一個(gè)消費(fèi)者線程,用于購(gòu)買(mǎi)產(chǎn)品。另外,我們創(chuàng)建一個(gè)隊(duì)列類Queue,生產(chǎn)線程生產(chǎn)的產(chǎn)品將放置到該隊(duì)列中,然后消費(fèi)者線程在該隊(duì)列中取走產(chǎn)品。
2.實(shí)現(xiàn)該模式的要點(diǎn):
首先必須讓生產(chǎn)者線程與消費(fèi)者線程達(dá)到同步,也就是說(shuō),當(dāng)生產(chǎn)者線程生產(chǎn)出產(chǎn)品后,消費(fèi)者才能去取,依此輪回。當(dāng)生產(chǎn)者線程放置產(chǎn)品到隊(duì)列中時(shí),隊(duì)列要檢查隊(duì)列是否已滿,如已滿,則等待消費(fèi)者線程將產(chǎn)品取走,否則放置產(chǎn)品到隊(duì)列中。當(dāng)消費(fèi)者線程在隊(duì)列中取產(chǎn)品時(shí),隊(duì)列也要檢查隊(duì)列是否為空,如果為空,則等待生產(chǎn)者線程放置產(chǎn)品到隊(duì)列,否則在隊(duì)列中取走產(chǎn)品。
3.源代碼:
class MainThread
{
public static void main(String[] args)
{
Queue queue=new Queue();
Producer producer=new Producer(queue);
Consumer consumer=new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();
}
}
/*注意:wait notify notifyAll只能在同步方法或內(nèi)步塊中調(diào)用*/
class Queue
{
int product=0;
boolean bfull=false;
public synchronized void setProduct(int product)
{
if(bfull)//如果隊(duì)列已滿,則調(diào)用wait等待消費(fèi)者取走產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開(kāi)始放置產(chǎn)品到隊(duì)列中*/
this.product=product;
System.out.println("Producer set product:"+product);
bfull=true;
notify();//生產(chǎn)產(chǎn)品后通知消費(fèi)者取走產(chǎn)品
}
public synchronized void getProduct()
{
if(!bfull)//如果隊(duì)列是空的,則調(diào)用wait等待生產(chǎn)者生產(chǎn)產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開(kāi)始從隊(duì)列取走產(chǎn)品*/
System.out.println("Consumer get product:"+product);
bfull=false;
notify();//取走產(chǎn)品后通知生產(chǎn)者繼續(xù)生產(chǎn)產(chǎn)品
}
}
class Producer implements Runnable
{
Queue queue;
Producer(Queue queue)
{
this.queue=queue;
}
public void run()//生產(chǎn)線程
{
for(int i=1;i<=10;i++)
{
queue.setProduct(i);
}
}
}
class Consumer implements Runnable
{
Queue queue;
Consumer(Queue queue)
{
this.queue=queue;
}
public void run()//消費(fèi)線程
{
for(int i=1;i<=10;i++)
{
queue.getProduct();
}
}
}
輸出結(jié)果如下:
Producer set product:1
Consumer get product:1
Producer set product:2
Consumer get product:2
Producer set product:3
Consumer get product:3
Producer set product:4
Consumer get product:4
Producer set product:5
Consumer get product:5
Producer set product:6
Consumer get product:6
Producer set product:7
Consumer get product:7
Producer set product:8
Consumer get product:8
Producer set product:9
Consumer get product:9
Producer set product:10
Consumer get product:10