超越線程池:Java并發并沒有你想的那么糟糕

jopen 9年前發布 | 18K 次閱讀 React.js Java開發

React.js在Codecademy中的實際應用
很多人一直嘮叨著并發中的新概念。然而,許多開發人員還沒有機會把過多的注意力都放在上面。在這篇文章中,我們將帶您了解Java 8 streams、 Hadoop、 Apache Spark、 Quasar fibers以及響應式編程,讓你迅速入門。尤其是如果你不經常用它們的話。一句話,它并不遙遠,它就在我們身邊。

我們該怎么做?

談到并發,一種很好的方式來形容當前的問題是來回答幾個小問題以便更好的了解它:

  1. 它是一個數據處理任務么?如果是這樣的話,它可以分解為獨立的任務單元么?
  2. 操作系統、虛擬機和你的代碼之間的關系是什么?(本地線程 VS 輕量級線程)
  3. 有多少機器和處理器參與?(單核 VS 多核)

讓我們帶著問題,一起找出每個問題的最佳答案吧。

1、從線程池到并行流

在Java 8中,我們了解到新的流API接口,它允許應用聚集操作,如篩選、排序或者映射數據流。流允許我們做的另一件事情是,在多核機器上應用并行操作。并行流 ——通過把Fork/Join框架引入Java 7將線程間的工作分離。Java 6并發庫,我們看到了ExecutorService創建和處理我們的工作線程池,這不得不說是個進步。

Fork/Join也建立在ExecutorService之上,與傳統的線程主要的區別在于如何在線程和支持多核的機器間分配工作。用一個簡單的 ExecutorService你能完全控制工作線程之間的負載分布,確立每個任務的大小以便線程來處理。而Fork/Join,恰好有個work-stealing算法分配線程間的負載。簡而言之,這允許大型任務可以被分成更小單元,并在不同的線程間處理,最終我們可以知道——它是為了平衡線程間的 工作。然而,這并不是萬能的。

有時并行流會減慢你速度的,所以你需要多想想。在你的方法中使用parallelStream()會導致瓶頸和減速(在我們基準測試中跑慢了約15%左右)。假設我們已經運行多個線程,在其中一些我們使用parallelStream(),在線程池中添加越來越多的線程。這可以很容易超過我們的核心處理能力,由于增加了上下文轉換一切都慢下來了。

小結:在單機上并行流使線程處理抽象化,在一定程度上這會均衡核心間的負載。然而,如果你想高效使用它們,記住硬件是關鍵而不是生產更多的線程而超出機器的處理能力。

2、Apache Hadoop和Apache Spark

接下來談多核機器、 PB級數據和任務,這跟所有從推ter提到的Java或重載機器學習算法類似。談到Hadoop,不得不說這個應用廣泛的框架及它的組 件:Hadoop分布式文件系統(HDFS)、資源管理平臺(YARN)、數據處理模塊(MapReduce)和其他所需的類庫和工具(Common)。 在這些組件上層還有一些其他很受歡迎的可選工具,比如運行在HDFS上的數據庫(HBase)、查詢語言平臺(Pig)和數據倉庫基礎結構(Hive)。

Apache Spark 作為一種新數據處理模塊,以內存性能和快速執行的彈性分布式數據集(RDDs)而出名,不同于不能高效使用內存和磁盤的Hadoop MapReduce。Databricks公布的最新標準顯示當用少于10倍節點的時候,對1PB數據的排序Spark比Hadoop快三倍。

典型的Hadoop用例在于查詢數據,而Spark正以其快速的機器學習算法越來越出名。但這只是冰山一角,Databricks如是說:“Spark 使應用程序在Hadoop集群中運行在內存中快100倍,當運行在磁盤中時甚至快10倍”

小結:Spark是在Hadoop生態系統中的后起之秀,有一個常見的誤解是我們現在經常談它一些不合作或競爭的事情,但是我認為我們在這正在看到這個框架的發展。

3、Quasar fibers

我們有機會運行在Hadoop,現在讓我們回到單機。事實上,在Java多線程應用程序和集中在單線程上,讓我們眼光再長遠些。就我們而言,HotSpot JVM線程與本地系統線程相同,持有一個線程并且運行在”虛擬“線程中,這在fibers中都包含的。Java沒有原生的fibers支持,但是不要擔 心,Quasar通過Parallel Universe解決了我們的問題。

Quasar 是一個開源的JVM庫。它支持fibers(也稱為輕量級線程),并且還充當框架的角色,在后面中我會提到。在這上下文轉換是它本質的名字。當我們核心數 量有限,一旦本地線程數量越大我們就會收到越來越多的上下文開銷。一種解決這個問題的方式是fibers,使用單線程支持”多線程“。這看起來像threadcepiton的一個實例。

Fibers還可以被視為一個從線程池的進化,當我們通過應用并行流的時候避開了線程過載的危險。他們更容易衡量線程和允許令人可觀的并行”輕量“線程數量。它們不是為了取代線程,而是應該用在那些相對來說經常堵塞的代碼中,就如同擔任真正異步線程的角色。

小結:并行領域在Java并發性中正提供一種新的思路,雖然還沒有版本發布,但是值得一試。

4、Actor和響應式編程

在響應式的官方言論中,最新的釋義有4原則:響應、有彈性、靈活性和消息驅動。這基本意味著快速、容錯、可伸縮的和支持非阻塞通信。

讓我們看看Akka Actor是如果支持它的吧。簡單來講Actor有一個狀態和一個特定的行為,通過交換消息溝通彼此的郵箱。一個Actor系統作為一個整體應該被每個應 用程序創建,擁有一個層次結構將任務分解成更小的任務以便每個角色最多只有一個監督的角色。一個角色也可以處理這個任務,通過委托給另一個角色將其進一步 分解或在實例失敗的情況下,將它反饋給它的監督者。無論哪種方式,消息不應該包括行為或者共享可變的狀態,每個角色都有一個獨立的狀態和行為。

它是一個從大多數開發者在使用的并發模型的思考模式的轉移。盡管它起源于70年代,但是為了適應現代應用程序的要求,直到最近幾年它才復蘇。并行領域的Quasar也支持Actor,實現的主要區別在于fibers/輕量級線程。

小結:相反的,Actor模型需要管理線程池,讓它遠離使用工具包。今天面對這種應用程序處理的問題,尤其在我們可以處理擁有更多核心的高并發系統方面又重新有了關注。

總結

關于使用并發或者并行算法,我們今天通過介紹4種方法來解決問題來應對你需要的場景。希望這有 助于激起你的興趣,以及在這大談并發話題的現在開拓下你的視野。超越線程池,有一種將這委托給語言及它的工具的趨勢——關注新的技術并應用它而不是花費無 數個小時解決競態條件和鎖。

原文鏈接: takipi 翻譯: ImportNew.com - Martin
譯文鏈接: http://www.importnew.com/15410.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!