1.生產(chǎn)者-消費者模式實現(xiàn)概述
生產(chǎn)者與消費者模式是我們在編程過程中經(jīng)常會遇到的,就像我們生活那樣,生產(chǎn)者生產(chǎn)出產(chǎn)品,消費者去購買產(chǎn)品。在這里我們創(chuàng)建三個線程,一個主控線程main,用于創(chuàng)建各輔助線程;一個生產(chǎn)者線程,用于生產(chǎn)產(chǎn)品;一個消費者線程,用于購買產(chǎn)品。另外,我們創(chuàng)建一個隊列類Queue,生產(chǎn)線程生產(chǎn)的產(chǎn)品將放置到該隊列中,然后消費者線程在該隊列中取走產(chǎn)品。
2.實現(xiàn)該模式的要點:
首先必須讓生產(chǎn)者線程與消費者線程達到同步,也就是說,當生產(chǎn)者線程生產(chǎn)出產(chǎn)品后,消費者才能去取,依此輪回。當生產(chǎn)者線程放置產(chǎn)品到隊列中時,隊列要檢查隊列是否已滿,如已滿,則等待消費者線程將產(chǎn)品取走,否則放置產(chǎn)品到隊列中。當消費者線程在隊列中取產(chǎn)品時,隊列也要檢查隊列是否為空,如果為空,則等待生產(chǎn)者線程放置產(chǎn)品到隊列,否則在隊列中取走產(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)//如果隊列已滿,則調(diào)用wait等待消費者取走產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開始放置產(chǎn)品到隊列中*/
this.product=product;
System.out.println("Producer set product:"+product);
bfull=true;
notify();//生產(chǎn)產(chǎn)品后通知消費者取走產(chǎn)品
}
public synchronized void getProduct()
{
if(!bfull)//如果隊列是空的,則調(diào)用wait等待生產(chǎn)者生產(chǎn)產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開始從隊列取走產(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()//消費線程
{
for(int i=1;i<=10;i++)
{
queue.getProduct();
}
}
}
輸出結果如下:
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)者與消費者模式是我們在編程過程中經(jīng)常會遇到的,就像我們生活那樣,生產(chǎn)者生產(chǎn)出產(chǎn)品,消費者去購買產(chǎn)品。在這里我們創(chuàng)建三個線程,一個主控線程main,用于創(chuàng)建各輔助線程;一個生產(chǎn)者線程,用于生產(chǎn)產(chǎn)品;一個消費者線程,用于購買產(chǎn)品。另外,我們創(chuàng)建一個隊列類Queue,生產(chǎn)線程生產(chǎn)的產(chǎn)品將放置到該隊列中,然后消費者線程在該隊列中取走產(chǎn)品。
2.實現(xiàn)該模式的要點:
首先必須讓生產(chǎn)者線程與消費者線程達到同步,也就是說,當生產(chǎn)者線程生產(chǎn)出產(chǎn)品后,消費者才能去取,依此輪回。當生產(chǎn)者線程放置產(chǎn)品到隊列中時,隊列要檢查隊列是否已滿,如已滿,則等待消費者線程將產(chǎn)品取走,否則放置產(chǎn)品到隊列中。當消費者線程在隊列中取產(chǎn)品時,隊列也要檢查隊列是否為空,如果為空,則等待生產(chǎn)者線程放置產(chǎn)品到隊列,否則在隊列中取走產(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)//如果隊列已滿,則調(diào)用wait等待消費者取走產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開始放置產(chǎn)品到隊列中*/
this.product=product;
System.out.println("Producer set product:"+product);
bfull=true;
notify();//生產(chǎn)產(chǎn)品后通知消費者取走產(chǎn)品
}
public synchronized void getProduct()
{
if(!bfull)//如果隊列是空的,則調(diào)用wait等待生產(chǎn)者生產(chǎn)產(chǎn)品
{
try
{
wait();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*開始從隊列取走產(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()//消費線程
{
for(int i=1;i<=10;i++)
{
queue.getProduct();
}
}
}
輸出結果如下:
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