生產者與消費者java
⑴ java中關於消費者和生產者的問題
publicclassProcerConsumer_3
{
publicstaticvoidmain(String[]args)
{
=newSyncStack();
Procerp=newProcer(ss);
Consumerc=newConsumer(ss);
Threadt1=newThread(p);
Threadt2=newThread(c);
t1.start();
t2.start();
}
}
classSyncStack
{
intcnt=0;
char[]data=newchar[6];
publicsynchronizedvoidpush(charch)
{
while(cnt==data.length)
{
try
{
this.wait(); //wait是Object類中的方法,不是Thread中的方法,Thread中wait也是繼承自Object,
//this.wait();不是讓當前對象wait,而是讓當前鎖定this對象的線程wait,同時釋放對this的鎖定。
//注意:如果該對象沒有被鎖定,則調用wait方法就會報錯!即只有在同步方法或者同步代碼塊中才可以調用wait方法,notify同理
}
catch(Exceptione)
{
}
}
this.notify();//如果注釋掉了本語句,可能會導致消費線程陷入阻塞(如果消費線程本身執行很慢的話,則消費線程永遠不會wait,即永遠不會阻塞),因為消費線程陷入阻塞,所以生產線程因此不停生產產品達到6個後也陷入阻塞,最後顯示的肯定是「容器中現在共有6個字元!」
//this.notify();叫醒一個現在正在waitthis對象的一個線程,如果有多個線程正在waitthis對象,通常是叫醒最先waitthis對象的線程,但具體是叫醒哪一個,這是由系統調度器控制,程序員無法控制
//nority和notifyAll都是Object類中的方法
data[cnt]=ch;
cnt++;
System.out.printf("生產了:%c ",ch);
System.out.printf("容器中現在共有%d個字元! ",cnt);
}
publicsynchronizedcharpop()
{
charch;
while(0==cnt)
{
try
{
this.wait();
}
catch(Exceptione)
{
}
}
this.notify();//如果注釋掉了本語句,可能會導致生產線程陷入阻塞(如果生產線程本身執行很慢的話,則生產線程永遠不會wait,即永遠不會阻塞),因為生產線程陷入阻塞,消費線程因此不停取出產品,當容器中再也沒有產品時消費線程也陷入阻塞,最後顯示的肯定是「容器中現在共有0個字元!」
ch=data[cnt-1];
--cnt;
System.out.printf("取出:%c ",ch);
System.out.printf("容器中現在共有%d個字元! ",cnt);
returnch;
}
}
classProcerimplementsRunnable
{
SyncStackss=null;
publicProcer(SyncStackss)
{
this.ss=ss;
}
publicvoidrun()
{
charch;
//總共生產20個產品
for(inti=0;i<20;++i)
{
ch=(char)('a'+i);
ss.push(ch);
// try
// {
// Thread.sleep(500);
// }
// catch(Exceptione)
// {
// }
}
}
}
{
SyncStackss=null;
publicConsumer(SyncStackss)
{
this.ss=ss;
}
//總共消費20個產品
publicvoidrun()
{
for(inti=0;i<20;++i)
{
ss.pop();
try
{
Thread.sleep(500);
}
catch(Exceptione)
{
}
}
}
}
⑵ java中生產者和消費者問題
好不好,要看情況,單這樣,提不提都問題不大。
類的架構,由設計者決定。
this 是指當前類的當前實例
⑶ java多生產者和多消費者
public static void main(String[] args) {
Buffer buffer=new Buffer(); //創建一個臨界區對象
new Procer(buffer,100).start(); //創建一個生產者對象,並啟動其線程
new Consumer(buffer,200).start(); //創建一個消費者對象,並啟動其線程
new Consumer(buffer,201).start(); //創建第二個消費者對象,並啟動其線程
}
這一段代碼,多加入
new Consumer(buffer,201).start(); //創建第二個消費者對象,並啟動其線程
多加一段代碼創建一個消費者
多加入
new Procer(buffer,100).start();
創建一個生產者。
想要很多生產者和消費者?加就是了啊。
第四個文件 Buffer.java
這個是實現同步的主要緩存類。想要實現同步
在每個方法的聲明前都加入synchronized 就行
synchronized 線程鎖,很好用的。源代碼已經加入了
就比如
public synchronized void put(int value) { //同步方法控制臨界區內容寫入
⑷ Java線程生產者與消費者
改成這樣就可以了
class WoTou {
int id;
WoTou(int id) {
this.id=id;
}
public String toString() {
return "WoTou"+id;
}
}
class SynStack {
WoTou[] ss = new WoTou[6];
int index;
SynStack(int index) {
this.index=index;
}
public synchronized void push(WoTou wt) {
while(index==ss.length) {
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
ss[index]=wt;
index++;
}
public synchronized WoTou pop() {
while(index==0) {
try {
this.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
return ss[index];
}
}
class Procer implements Runnable{
SynStack syn;
Procer(SynStack syn) {
this.syn=syn;
}
public void proceWoTou() {
for(int i=0;i<20;i++) {
WoTou wt = new WoTou(i);
syn.push(wt);
System.out.println("生產了一個"+wt);
try {
Thread.sleep(200);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
this.proceWoTou();
}
}
class Consumer implements Runnable{
SynStack syn;
Consumer(SynStack syn) {
this.syn=syn;
}
public void consumerWoTou() {
for(int i=0;i<20;i++) {
WoTou wt=syn.pop();
System.out.println("消費了一個"+wt);
try {
Thread.sleep(500);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
this.consumerWoTou();
}
}
public class ProcerConsumer {
public static void main(String[] args) {
SynStack syn = new SynStack(0);
Procer p = new Procer(syn);
Consumer c = new Consumer(syn);
new Thread(p).start();
new Thread(c).start();
}
}
⑸ 用JAVA編寫消費者和生產者問題
似乎要用到線程和通道,好好看下那兩塊的內容吧,具體有什麼不會的地方再把問題補充一下.要原代碼的話......
怎麼還不截題?叫你打敗了,見清華大學出版社<<面向對象的程序設計與JAVA>>P228-P229.
public class Box
{
private int value;
private boolean available = false;
public synchronized int get()
{
while (available == false)
{
try
{
// 等待生產者寫入數據
wait();
} catch (InterruptedException e)
{
// TODO: handle exception
e.printStackTrace();
}
}
available = false;
// 通知生產者數據已經被取走,可以再次寫入數據
notifyAll();
return value;
}
public synchronized void put(int value)
{
while (available == true)
{
try
{
// 等待消費者取走數據
wait();
} catch (InterruptedException e)
{
// TODO: handle exception
e.printStackTrace();
}
}
this.value = value;
available = true;
// 通知消費者可以來取數據
notifyAll();
}
}
package lly;
public class Consumer extends Thread
{
private Box box;
private String name;
public Consumer(Box b, String n)
{
box = b;
name = n;
}
public void run()
{
int value = 0;
for (int i = 1; i < 6; i++)
{
value = box.get();
System.out.println("Consumer " + name + " consumed: " + value);
try
{
sleep((int) (Math.random() * 10000));
} catch (InterruptedException e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
}
package lly;
public class Procer extends Thread
{
private Box box;
private String name;
public Procer(Box b, String n)
{
box = b;
name = n;
}
public void run()
{
for (int i = 1; i < 6; i++)
{
box.put(i);
System.out.println("Procer " + name + " proced: " + i);
try
{
sleep((int) (Math.random() * 10000));
} catch (InterruptedException e)
{
// TODO: handle exception
e.printStackTrace();
}
}
}
}
package lly;
public class ProcerConsumer
{
/**
* @param args
*/
public static void main(String[] args)
{
// TODO 自動生成方法存根
Box box = new Box();
Procer p = new Procer(box, "p");
Consumer c = new Consumer(box, "c");
p.start();
c.start();
}
}
⑹ 用Java對生產者和消費者進行模擬
北信科的么
⑺ java 生產者與消費者 的簡單問題
1 toString是在控制台列印對象的時候會調用的對象的方法。。比如你定義個Sx對象sx。。然後System.out.println(sx);就會先調用sx的toString方法。。將得到的String對象列印在控制台。。每個類都繼承自Object。。Object類裡面有個toString方法。。返回的是該對象在內存中的地址。。如果你不重寫這個方法。。列印出來的東西你看不明白的。。
2 java中數據類型有基本類型(int那些)和引用類型(就是所謂的對象)。。java中數組是對象。。每個數組對象都有一個length屬性。。值是這個數組的元素個數。。對象調用屬性是不需要括弧的。。方法才需要。。
3 kuang ss=null;就是定義一個kuang對象ss。。其初始值為null。。為null的對象在內存中什麼都沒有
int index=0; Wotou[] tou=new Wotou[6];這兩個都不是為空的。。都有具體的初始值。。
4 Wotou wt=ss.pop();表示定義一個Wotou對象wt。。並將調用ss對象的pop方法的返回值賦值給wt對象。。具體你看下kuang 類的pop方法就知道了。。
⑻ java Thread生產者與消費者模型
你沒看見有while條件嗎,你看看他的執行順序
public synchronized void push()在
index==arrWT.length 時 wait 等待 pop() 喚醒
public synchronized WoTou pop()
在index==0 是wait 等待 push() 喚醒
開始index==0 如果pop()先執回行他會wait()
然後push()執行讓答index+1
然後喚醒push喚醒pop()接著就是無順序執行
當index再次為0時就重復上面的過程
到那個index==arrWT.length時就會是
push等待pop喚醒了。
⑼ JAVA模擬生產者與消費者實例
class Procter extends Thread
{
Queue q;
Procter (Queue q)
{
this.q=q;
}
public void run()
{
for(int i=0;i<10;i++)
{
q.put(i);
System.out.println("procter :"+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this.q=q;
}
public void run()
{
while(true)
{
System.out.println("Consumer:"+q.get());
}
}
}
class Queue
//key
{
int value;
boolean bFull=false;
public synchronized void put(int i)
{
if(!bFull)
{
value=i;
bFull=true;
notify();//必須用在synchronized
}
try {
wait();//必須捕獲異常
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized int get()
{
if(!bFull)
try
{
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bFull=false;
notify();
return value;
}
}
public class test //測試類
{
public static void main(String[] args)
{
Queue q=new Queue();
Procter p=new Procter(q);
Consumer c=new Consumer(q);
p.start();
c.start();
}
}