摘要:因此將變量存放于獨立的緩存行中,也有助于變量在多線程訪問是的性能提升實戰高并發程序設計,大量的高并發庫都會采用這種技術。
在Java程序中,多線程幾乎已經無處不在。與單線程相比,多線程程序的設計和實現略微困難,但通過多線程,我們卻可以獲得多核CPU帶來的性能飛躍,從這個角度說,多線程是一種值得嘗試的技術。那么如何寫出高效的多線程程序呢?
有關多線程的誤區:線程越多,性能越好
不少初學者可能認為,線程數量越多,那么性能應該越好。因為程序給我們的直觀感受總是這樣。一個兩個線程可能跑的很難,線程一多可能就快了。但事實并非如此。因為一個物理CPU一次只能執行一個線程,多個線程則意味著必須進行線程的上下文切換,而這個代價是很高的。因此,線程數量必須適量,最好的情況應該是N個CPU使用N個線程,并且讓每個CPU的占有率都達到100%,這種情況下,系統的吞吐量才發揮到極致。但現實中,不太可能讓單線程獨占CPU達到100%,一個普遍的愿意是因為IO操作,無論是磁盤IO還是網絡IO都是很慢的。線程在執行中會等待,因此效率就下來了。這也就是為什么在一個物理核上執行多個線程會感覺效率高了,對于程序調度來說,一個線程等待時,也正是其它線程執行的大好機會,因此,CPU資源得到了充分的利用。
盡可能不要掛起線程
多線程程序免不了要同步,最直接的方法就是使用鎖。每次只允許一個線程進入臨界區,讓其它相關線程等待。等待有2種,一種是直接使用操作系統指令掛起線程,另外一種是自旋等待。在操作系統直接掛起,是一種簡單粗暴的實現,性能較差,不太適用于高并發的場景,因為隨之而來的問題就是大量的線程上下文切換。如果可以,嘗試一下進行有限的自旋等待,等待不成功再去掛起線程也不遲。這樣很有可能可以避免一些無謂的開銷。JDK中ConcurrentHashMap的實現里就有一些自旋等待的實現。此外Java虛擬機層面,對synchronized關鍵字也有自旋等待的優化。
善用“無鎖”
阻塞線程會帶來性能開銷,因此,一種提供性能的方案就是使用無鎖的CAS操作。JDK中的原子類,如AtomicInteger正是使用了這種方案。在高并發環境中,沖突較多的情況下,它們的性能遠遠好于傳統的鎖操作(《實戰Java高并發程序設計》 P158)。
處理好“偽共享”問題
大家知道,CPU有一個高速緩存Cache。在Cache中,讀寫數據的最小單位是緩存行,如果2個變量存在一個緩存行中,那么在多線程訪問中,可能會相互影響彼此的性能。因此將變量存放于獨立的緩存行中,也有助于變量在多線程訪問是的性能提升(《實戰Java高并發程序設計》 P200),大量的高并發庫都會采用這種技術。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65379.html
摘要:阿姆達爾定律定律是計算機科學中非常重要的定律。它定義了串行系統并行化后的加速比的計算公式和理論上線。需要從根本上修改程序的串行行為,提高系統內可并行化的模塊比重,在此基礎上,合理增加并行處理器數量,才能以最小的投入,得到最大的加速比。 有關為什么要使用并行程序的問題前面已經進行了簡單的探討。總的來說,最重要的應該是處于兩個目的。 第一,為了獲得更好的性能; 第二,由于業務模型的需要,確...
摘要:系統級線程核心級線程由操作系統內核進行管理。值得注意的是多線程的存在,不是提高程序的執行速度。實現多線程上面說了一大堆基礎,理解完的話。虛擬機的啟動是單線程的還是多線程的是多線程的。 前言 之前花了一個星期回顧了Java集合: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼剖析】 LinkedHashMa...
摘要:前言談到并行,我們可能最先想到的是線程,多個線程一起運行,來提高我們系統的整體處理速度為什么使用多個線程就能提高處理速度,因為現在計算機普遍都是多核處理器,我們需要充分利用資源如果站的更高一點來看,我們每臺機器都可以是一個處理節點,多臺機器 前言 談到并行,我們可能最先想到的是線程,多個線程一起運行,來提高我們系統的整體處理速度;為什么使用多個線程就能提高處理速度,因為現在計算機普遍都...
摘要:虛擬機所處的區域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機總共運行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數量為。 本文主要從GC(垃圾回收)的角度試著對jvm中的內存分配策略與相應的垃圾收集器做一個介紹。 注:還是老規矩,本著能畫圖就不BB原則,盡量將各知識點通過思維導圖或者其他模型圖的方式進行說明。文字僅記錄額外的思考與心得,以及其他特殊情況 內存...
摘要:串行與并行可以分為串行與并行兩種,串行流和并行流差別就是單線程和多線程的執行。返回串行流返回并行流和方法返回的都是類型的對象,說明它們在功能的使用上是沒差別的。唯一的差別就是單線程和多線程的執行。 Stream是什么 Stream是Java8中新加入的api,更準確的說: Java 8 中的 Stream 是對集合(Collection)對象功能的增強,它專注于對集合對象進行各種非常便...
閱讀 832·2021-09-07 09:58
閱讀 2689·2021-08-31 09:42
閱讀 2863·2019-08-30 14:18
閱讀 3092·2019-08-30 14:08
閱讀 1837·2019-08-30 12:57
閱讀 2763·2019-08-26 13:31
閱讀 1305·2019-08-26 11:58
閱讀 1059·2019-08-23 18:06