生產者消費者問題的兩種寫法

2021-09-29 09:16:50 字數 2904 閱讀 1130

問題:乙個固定容量的同步容器,有get方法和put方法,和size()方法。n個生產者不斷往裡面put,m個消費者不斷從中get。

方式一:object的wait和notify

public class testpandc }}

,"p"

+i);

t.start()

;}try catch (interruptedexception e)

//5個消費者,每個人吃5個

for(

int i=

0;i<

5;i++)}

},"c"+i)

; t.

start()

;}}}

class mycontainer

public synchronized void

put(t t)

catch (interruptedexception e)

} system.out.

println

(thread.

currentthread()

.getname()

+"生產第"

+size+

"個")

; list.

add(t)

; size++

;notifyall()

;//為什麼用notifyall(),不用notify()}

public synchronized t get()

catch (interruptedexception e)

}//叫醒後,並且搶到鎖後,從這裡開始執行

system.out.

println

(thread.

currentthread()

.getname()

+"開始消費第"

+size+

"個")

; size--

;notifyall()

;return list.

removefirst()

;}public /*synchronized*/

intsize()

}

這種方式有兩個重點:

為什麼wait外面用while不能用if?

因為wait()是會釋放鎖的,那麼即使後來,被消費者叫醒,它也是沒有鎖的,需要重新去搶鎖。既然有多個生產者,多個生產者都會去搶,假設其中乙個搶到了,並且把容器又做滿了,那麼其他生產者再搶到時,如果是if,那麼它不會再去判斷了,而是繼續執行wait()後面的**,這樣可能就超了。所以要用while,wait醒來搶到鎖之後還要再檢查一遍有沒有被其他被叫醒的生產者填滿。

這裡即使用if double check也是一樣不行。因為if(size==column)那還得重新wait,醒來又是和上面一樣的問題了。

wait()在99%的情況下都是和while搭配!

為什麼要用notifyall,而不能用notify()

因為notify是隨機叫醒乙個執行緒,假如說現在容器裡沒有東西了,生產者生產了乙個,叫醒了乙個消費者,這個消費者消費了,然後又沒了,去notify,但是這時叫醒的是另外乙個消費者,這個消費者一看沒有就會一直等,也不會再叫醒其他人了。就會陷入死迴圈。

盡量用notifyall(),少用notify()(除非個別情況,如只有乙個執行緒)

方式二:lock和condition的await和signal

public class testpandc2 }}

,"p"

+i);

t.start()

;}try catch (interruptedexception e)

//5個消費者,每個人吃5個

for(

int i=

0;i<

5;i++)}

},"c"+i)

; t.

start()

;}}}

class mycontainer2

public void

put(t t)

catch (interruptedexception e)

} system.out.

println

(thread.

currentthread()

.getname()

+"生產第"

+size+

"個")

; list.

add(t)

; size++

; consumer.

signalall()

;//可以更精確控制叫醒的執行緒

lock.

unlock()

;}public t get()

catch (interruptedexception e)

}//叫醒後,並且搶到鎖後,從這裡開始執行

system.out.

println

(thread.

currentthread()

.getname()

+"開始消費第"

+size+

"個")

; size--

; producer.

signalall()

; lock.

unlock()

;return list.

removefirst()

;}public /*synchronized*/

intsize()

}

借用別人的一張圖:

生產者與消費者的兩種方式

synchronized版,使用wait notify public class demo01 catch interruptedexception e 生產者 start 消費者a去購買商品 new thread catch interruptedexception e 消費者a start 消費...

生產者消費者問題

public class producer consumer class godown public godown int num public synchronized void produce int n catch interruptedexception e curr num n syste...

生產者 消費者問題

在學習程序互斥中,有個著名的問題 生產者 消費者問題。這個問題是乙個標準的 著名的同時性程式設計問題的集合 乙個有限緩衝區和兩類執行緒,它們是生產者和消費者,生產者把產品放入緩衝區,相反消費者便是從緩衝區中拿走產品。生產者在緩衝區滿時必須等待,直到緩衝區有空間才繼續生產。消費者在緩衝區空時必 須等待...