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