生產者消費者模型

2021-10-02 19:31:27 字數 3539 閱讀 7779

兩個程序共享乙個緩衝區,乙個程序向緩衝區中寫入資料(生產者),另乙個程序從緩衝區中讀取資料(消費者)。當緩衝區被寫滿時,生產者就必須進入掛起狀態,直到消費者從緩衝區中取走資料時,生產者才能繼續向緩衝區中放資料。同樣當緩衝區沒有資料時,消費者程序就必須進入掛起狀態,直到生產者向緩衝區中放入資料時,消費者才能被喚醒繼續從緩衝區中取走資料。

先實現乙個佇列:

public class arrayqueue 

array[rear++] = val;

if(rear == array.length)

size++;

}public int take()

int val = array[front];

front = (front+1)%array.length;

size--;

return val;

}public int getsize()

1.建立生產者、消費者類並整合執行緒,通過thread的構造方法命名兩個執行緒;

2.通過printwriter將生產的元素和消費的元素寫到文字中用於比對;

3.覆寫run()方法,乙個呼叫put()進行生產,乙個呼叫take()進行消費;

private static arrayqueue queue = new arrayqueue();

private static class producer extends thread

printwriter printwriter;

catch (ioexception e)

}@override

public void run() catch (runtimeexception e)

}while (true);

}printwriter.close();

}}private static class customer extends thread

printwriter printwriter;

catch (ioexception e)

}@override

public void run() catch (runtimeexception e)

}while (true);

}printwriter.close();

}}public static void main(string args)

單生產者、單消費者

private int array = new int[10];

private volatile int size = 0;

private int front = 0;

private int rear = 0;

public void put(int val) throws interruptedexception

}array[rear++] = val;

if(rear == array.length)

synchronized (this)

}public int take() throws interruptedexception

}int val = array[front];

front = (front+1)%array.length;

synchronized (this)

return val;

}public int getsize()

private static arrayqueue queue = new arrayqueue();

private static class producer extends thread

@override

public void run() catch (interruptedexception e) }}

}private static class customer extends thread

@override

public void run() catch (interruptedexception e) }}

}public static void main(string args) throws interruptedexception

1、用volatile保證size變數的有序性從而保證執行緒安全;

2、size==0 或 size==array.length 時呼叫wait()方法,使執行緒進入等待集;

3、當size++或size--時通過synchronize鎖住當前引用,並且呼叫notify()喚醒生產者或消費者,保證執行緒安全;

注意:多消費者或多生產者時執行緒安全沒法保證!

private int array = new int[10];

private volatile int size = 0;

private int front = 0;

private int rear = 0;

//在take()和put()方法上加synchronize,效率低

public synchronized void put(int val) throws interruptedexception

array[rear++] = val;

if(rear == array.length)

synchronized (this)

}public synchronized int take() throws interruptedexception

int val = array[front];

front = (front+1)%array.length;

synchronized (this)

return val;

}public int getsize()

private static arrayqueue queue = new arrayqueue();

private static class producer extends thread

@override

public void run() catch (interruptedexception e) }}

}private static class customer extends thread

@override

public void run() catch (interruptedexception e) }}

}public static void main(string args) throws interruptedexception

while (producer.isalive())

}

1、當消費者和生產者執行緒都進入等待集,喚醒是隨機的,因此使用notifyall()喚醒全部執行緒,while()的作用也在此;

2、synchronize是為了防止在while語句判斷完後立馬被搶走cpu,從而導致執行緒不安全;

生產者消費者模型

1.生產者消費者問題 producer consumer 有限緩衝,多執行緒同步。生產者執行緒和消費者執行緒共享固定大小緩衝區。2.關鍵是保證生產者不會再緩衝區滿時加入資料,消費者不會在緩衝區空時消耗資料。3.解決辦法 讓生產者在緩衝區滿時休眠,等下次消費者消耗緩衝區中的資料的時候,生產者才能被喚醒...

生產者消費者模型

生產者與消費者 3,2,1 三種關係 生產者與消費者 互斥,同步 消費者與消費者 互斥 生產者與生產者 互斥 條件變數 int pthread cond destroy pthread cond t cond int pthread cond init pthread cond t restrict...

生產者消費者模型

當佇列滿時,生產者需要等待佇列有空間才能繼續往裡面放入商品,而在等待的期間內,生產者必須釋放對臨界資源 即佇列 的占用權。因為生產者如果不釋放對臨界資源的占用權,那麼消費者就無法消費佇列中的商品,就不會讓佇列有空間,那麼生產者就會一直無限等待下去。因此,一般情況下,當佇列滿時,會讓生產者交出對臨界資...