多線程,單線程,線程安全,同步,異步的區別


本文是總結知乎上面的知識點,雖然忘記了具體的鏈接地址,但是還是非常感謝知乎里面各位大神的分享!

 

java 中使用 synchronized 是用來 表示該資源或者該方法是不能進行多個線程的共享的,所以當多個線程都在請求該資源的時候,就跟串行是一樣的也就是單線程效果一樣,但是當不為共享的時候就可以利用並發來大大的提高系統的效率。

1、多線程並不解決軟件執行效率和你硬件系統的瓶頸,它只是達到更高效使用你的硬件系統資源。
2、從本質上來說,單核單CPU不存在並行,即使多線程也是串行,多線程不會提高CPU利用率。
3、對於同步塊與單線程執行比較,並不存在多少性能差異,如果相比較,同步塊的執行效率還要大大低於單線程程序,如果設計差,可能還是災難級的。因為同步本身就需要占用系統資源和CPU片段,而且每個線程自己也需要占用資源,如果多線程達不到多線程的優勢,那么它本身就會降低效率。


例如下載一首歌曲為10M,采用單線程的方式,那么只能從開頭到結束,如果中途出現了什么問題,那么它就不能往下執行了,如果使用多線程,例如開辟2個線程,那么每個線程可以下載5M,這就涉及到一個斷點下載的問題了,效率肯定比單線程快,如果里面包含synchronized方法,那么第一個線程在進行任務了,突然出現了什么問題,那么我們可以讓第二個線程執行任務,相比於單線程來說效率更高
其實設計synchronized的目的是在使用多線程的時候從安全性方面去考慮的,例如在一個方法中修改一個全局變量,如果使用單線程當然是沒什么問題的,一個線程進來我就自己一個人修改,也不會影響什么,但是如果在多線程環境中,很多線程同時訪問這個方法修改全局變量,那么就可能會出問題了,可能你爭我搶(分配到CPU資源)把這個全局變量改的不成樣子了,所以考慮安全性,我們使用synchronized,如果有多個線程,表示你們得一個一個排隊來,如果我進去方法里面了,那么我就把門給鎖上,只有我一個在里面修改全局變量,你們都不能進來,等我處理完成了,我再釋放鎖,然后讓下一個進來修改,這樣也就確保了全局變量不會被改的亂七八糟不成樣子了,因為很多項目中會有這樣的需求,所以我們得根據需求來確定相應的解決方案!!



舉個例子來說,你有100份英語卷子,有聽力,選擇題和作文三部分;每部分做完之后,必須把100份卷子都交上來以后,才能拿下一部分。
一起拿下一部分的動作就叫做同步,
你是拿叫一個同學做,還是叫100個同學做呢?(單線程,還是多線程)


一個進程中如果有多個線程,那么執行多線程中的非同步代碼時比一個進程只有一個線程快。如果進程中有多個線程但是每個線程的所有代碼都需要同步的話就和進程只有一個線程的效率是相同的。



線程是在進程中的,一個進程可以有多個線程,單個線程不能脫離進程存在。
所以樓主的問題就是單進程中多線程為何優於多進程(每個進程對應一個線程),當同步時,看上去也都是一個線程在執行,但前者的效率將遠遠高於后者。因為多線程是共享進程中的數據的,共享數據使得線程之間的通信比進程間通信更快更有效。同時,很多時候,線程相對於進程屬於輕量級的,更便於創建和銷毀。



ArrayList和Vector有什么區別?HashMap和HashTable有什么區別?StringBuilder和StringBuffer有什么區別?這些都是Java面試中常見的基礎問題。面對這樣的問題,回答是:ArrayList是非線程安全的,Vector是線程安全的;HashMap是非線程安全的,HashTable是線程安全的;StringBuilder是非線程安全的,StringBuffer是線程安全的。



非線程安全是指多線程操作同一個對象可能會出現問題。而線程安全則是多線程操作同一個對象不會有問題。
線程安全必須要使用很多synchronized關鍵字來同步控制,所以必然會導致性能的降低。
所以在使用的時候,如果是多個線程操作同一個對象,那么使用線程安全的Vector;否則,就使用效率更高的ArrayList。


非線程安全!=不安全
有人在使用過程中有一個不正確的觀點:我的程序是多線程的,不能使用ArrayList要使用Vector,這樣才安全。
非線程安全並不是多線程環境下就不能使用。注意我上面有說到:多線程操作同一個對象。注意是同一個對象。比如最上面那個模擬,就是在主線程中new的一個ArrayList然后多個線程操作同一個ArrayList對象。
如果是每個線程中new一個ArrayList,而這個ArrayList只在這一個線程中使用,那么肯定是沒問題的。

線程安全的實現
線程安全是通過線程同步控制來實現的,也就是synchronized關鍵字。



------------------------------------------------------同步異步區別--------------------------------------------------------

他們最大的區別:同步需要等待,而異步無需等待。

例子:
普通B/S模式(同步)AJAX技術(異步)

同步:提交請求->等待服務器處理->處理完畢返回 這個期間客戶端瀏覽器不能干別的事。

異步: 請求通過事件觸發->服務器處理(這是瀏覽器仍然可以作其他事情)->處理完畢。

說的再通俗易懂點

同步是按順序執行,執行完一個再執行下一個,需要等待、協調運行。

異步就是彼此獨立,在等待某事件的過程中繼續做自己的事,不需要等待這一事件完成后再工作。

線程就是異步實現的一個方式。

異步是讓調用方法的主線程不需要同步等待另一線程的完成,從而可以讓主線程干其它的事情。


異步和多線程並不是一個同等關系,異步是最終目的,多線程只是我們實現異步的一種手段。

異步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回而可以做其它的事情。

實現異步可以采用多線程技術或則交給另外的進程來處理。


同步和異步區別:(好處和壞處)

同步可以避免出現死鎖,讀臟數據的發生。

一般共享某一資源的時候用,如果每個人都有修改權限,同時修改一個文件,有可能使一個人讀取另一個人已經刪除的內容,就會出錯,

同步就會按順序來修改。

但是,同步需要等待資源訪問結束,浪費時間,效率低。



異步則可以提高效率,
現在cpu都是雙核,四核,異步處理的話可以同時做多項工作,當然必須保證是可以並發處理的。

但是安全性較低。

http://blog.csdn.net/xiao__gui/article/details/8934832


其實,異步是目的,而多線程是實現這個目的的方法。異步是說,A發起一個操作后(一般都是比較耗時的操作,如果不耗時的操作就沒有必要異步了),可以繼續自顧自的處理它自己的事兒,不用干等着這個耗時操作返回

  而線程的適用范圍則是那種需要長時間CPU運算的場合,例如耗時較長的圖形處理和算法執行。但是往 往由於使用線程編程的簡單和符合習慣,所以很多朋友往往會使用線程來執行耗時較長的I/O操作。這樣在只有少數幾個並發操作的時候還無傷大雅,如果需要處 理大量的並發操作時就不合適了。

異步與多線程,從辯證關系上來看,異步和多線程並不時一個同等關系,異步是目的,多線程只是我們實現異步的一個手段.什么是異步:異步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回.實現異步可以采用多線程技術或則交給另外的進程來處理

=========================================================================

線程池的實現方法與線程是不一樣的.初始化時在線程池里的線程為0.當進程需要一個線程時,創建一個線程,由此線程執行用戶的方法.需要注意的是,此線程執行完后並不立即銷毀,而是掛起等待,如果有其他方法需要執行,回喚醒進行處理.只有當它等到40秒(沒有官方記錄,有可能是其它數字)還沒有任務執行時才喚醒自己,並銷毀自己,釋放資源.當然,如果線程池中的線程不夠處理任務時,會再次創建一個新線程進行執行.


異步執行也得執行,不在當前線程執行,當然得去另外一個線程執行。異步通常用系統線程池的線程,通常情況下性能好些。(因為可以多次利用,申請時不需要重新申請一個線程,只需要從池里取就行了。)異步是一種效果,多線程是一種具體技術。可以說,用“多線程”實現“異步”。

異步和多線程是兩個不同的概念,不能這樣比較.異步請求一般用在IO等耗時操作上,他的好處是函數調用立即返回,相應的工作線程立即返還給系統以供重用。由於系統的線程資源是非常寶貴的,通常有一定的數目限制,如.net默認是25。若使用異步方式,用這些固定數目的線程在固定的時間內就可以服務更多的請求,而如果用同步方式,那么每個請求都自始至終占用這一個線程,服務器可以同時服務的請求數就少了。當異步操作執行完成后,系統會從可用線程中選取一個執行回調程序,這時的這個線程可能是剛開始發出請求的那個線程,也可能是其他的線程,因為系統選取線程是隨機的事情,所以不能說絕對不是剛開始的那個線程。多線程是用來並發的執行多個任務。

不過有個問題,異步有時優先級比主線程還高。這個特點和多線程不同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM