wait與notify的運行時概念

wait與notify最好不要用。必定要用就要規劃好所有的運行計劃。由於它是與運行時相關的。 程序員

跟運行時相關的意思是,也許你在代碼中有三個地方調用了這個對象的wait,也在三個地方調用了這個對象的notify,這個不是成對使用。成對使用是指運行時必須是一對一的。若是10次運行WAIT而沒有獲得10次NOTIFY,那麼就會有線程被阻塞在阻塞隊列中不得而出,程序就會死掉。 編程

而且,即便規劃好了這樣的NOTIFY,可是若是一不當心浪費掉了其中的幾個NOTIFY,那麼也會挺麻煩的。由於浪費掉的NOTIFY指它被調用的時機發生時,鎖對象的等待隊列中並無其它的線程。隊列是空的。因此此次機會失敗了。 安全

好比你能夠隨時調用一個對象的NOTIFY方法,這個操做跟MAP裏面的REMOVE同樣,它是沒有反作用的。它要麼REMOVE成功,要麼什麼都不幹。若是它什麼都不幹,就說明你進行了錯誤的操做。而NOTIFY錯誤是致命的,除非你很幸運。也就是說由於你的規劃原本就是錯誤的,因此錯錯得正,這個機會 是有的。 多線程

還要注意的就是WAIT隊列與鎖隊列是不一樣的。鎖其實沒有隊列,它沒有狀態,只有行爲。好比一個線程嘗試獲取一個鎖,失敗了就是失敗了,可是不會被記錄。由於同步操做是高效率的操做,底層是使用原語完成的。裏面的原理很是複雜,特別在1.5之後,很是很是複雜。有一個逐漸嚴肅化的過程,從什麼原子鎖到輕量級鎖,共享鎖一大堆。可是你只要知道JAVA的同步效率很是高就能夠了。你須要瞭解的不是SYNCHRONIZED快不快,而是你有沒有正確同步你的對象,有沒有正確理解或找到你的臨界代碼而且對這些代碼加以正確的同步。以及有沒有正確理解線程安全,同步嵌套,線程API的本質。 函數式編程

JAVA裏面,線程API實際上是虛擬機的調度接口。是虛擬機暴露其執行機制的窗口。你在寫線程相關的東西時,你其實已經在調度你的程序而並不僅是,好比說,做一個簡單的同步或者什麼東西。特別是在你開始使用sleep, wait, notify, join, yield, interrupt等這些方法時,系統極可能由於錯誤的調度陷入不可恢復的狀態並進而使系統中止工做。這個一方面直接引發系統當機,另外一方面還能夠引發內存泄漏。 函數

你對你的程序應該有一個完整的規劃。你應該隨時知道並控制你的程序運行。你應該知道全部的線程都在幹什麼,應該幹什麼,何時應該起動何時應該結束,系統穩定或待機狀態的定義,系統狀態的恢復,系統工做狀態的描述,而且另一點:一旦系統陷入當機或內存泄漏,對這個的容錯(線程容錯)。 線程

其實函數式編程的興起很大程度上就是由於多線程編程的困難。你要去控制機器,要去調度。因此又興起一大堆的好比,進程代數。這是個黑洞,無底洞,OO原本就已經很難搞了,再加上個這個,我看程序員到最後都得要求飛天。否則再過幾年可能什麼都幹不了啦。 設計

FP多是惟一的出路。 對象

其實多線程裏面,就單獨一個同步就根本就不具備任何可控制的特徵。咱們用的庫有同步,咱們上面的調用代碼又有同步。其實常常的,好比你調用了一些庫,但實際上這些庫共享了不少的東西,但你不可能所有都知道或者說去研究這些東西,而它又不是線程安全的。這時候就麻煩了。再者,誰知道你要在什麼地方用這些東西是吧? 接口

FP的問題是有限的內存。FP好像呈現出一種對內存的無止境的需求。若是能解決這個問題,FP的確比多線程好多了。

應該這麼說,馮諾依曼從一開始就不是爲多線程設計的。固然FP也不是,可是FP抽象程度足夠高因此沒有馮系統的問題。

咱們最終的目標仍然是問題域,而不是對機器與線程API的理解是吧。憑什麼咱們要去理解機器的調用機制?

相關文章
相關標籤/搜索