最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入了解Java語言中的并發(fā)性選項有何不同

 更新時間:2019年06月12日 11:26:22   作者:Neal Ford  
這篇文章主要介紹了深入了解Java語言中的并發(fā)性選項有何不同,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下

前言

Java™ 工程師在努力讓并發(fā)性容易為開發(fā)人員所用。盡管做了不少的改進,但并發(fā)性仍然是 Java 平臺的一個復(fù)雜、容易出錯的部分。一部分復(fù)雜之處在于理解語言本身中的并發(fā)性的低級抽象,這些抽象在您的代碼中填滿了同步的代碼塊。另一個復(fù)雜之處來自一些新庫,比如 fork/join,這些庫在某些場景中非常有用,但在其他場景中收效甚微。了解容易混亂的大量低級選項需要專業(yè)經(jīng)驗和時間。

脫離 Java 語言的優(yōu)勢之一是,能夠改善和簡化并發(fā)性等區(qū)域。每種 Java 下一代語言都為此問題提供了獨特的答案,利用了該語言的默認(rèn)編程風(fēng)格。在本期文章中,我首先將會介紹函數(shù)式編程風(fēng)格的優(yōu)勢:輕松并行化。我會深入分析 Scala 和 Groovy 的細節(jié)(下一期文章將全面介紹 Clojure)。然后介紹 Scala actor。

完美數(shù)

數(shù)學(xué)家尼科馬庫斯(誕生于公元前 6 世紀(jì))將自然數(shù)分為惟一的完美數(shù)(perfect number)、過剩數(shù)(abundant number) 或虧數(shù)(deficient number)。一個完美數(shù)等于它的正因數(shù)(不包括它本身)之和。例如,6 是一個完美數(shù),因為它的因數(shù)是 1、2、3 和 6,28 也是完美數(shù) (28 = 1 + 2 + 4 + 7 + 14)。過剩數(shù)的因素之和大于該數(shù),虧數(shù)的因數(shù)之和小于該數(shù)。

這里使用完美數(shù)分類法是為了方便介紹。除非要處理大量數(shù)字,是否查找因素對于從并行化中獲益而言是一個微不足道的問題。使用更多線程可帶來一些益處,但線程之間的切換開銷對細粒度的作業(yè)而言代價很高。

讓現(xiàn)有代碼并行化

在 “函數(shù)式編碼風(fēng)格” 那一期的文章中,我們鼓勵您使用更高級的抽象,比如化簡、映射和過濾器,而不是迭代。此方法的優(yōu)勢之一是容易并行化。

我的 函數(shù)式思維 系列的讀者熟悉包含完美數(shù) 的數(shù)字分類模式(參見 完美數(shù) 邊欄)。我在該系列中展示的任何解決方案都沒有利用并發(fā)性。但是因為這些解決方案使用了轉(zhuǎn)換函數(shù),比如 map,所以我可以在每種 Java.net 語言中做極少的工作來創(chuàng)建并行化的版本。

清單 1 是完美數(shù)分類器的一個 Scala 示例。

清單 1. Scala 中的并行完美數(shù)分類器

object NumberClassifier {
def isFactor(factor: Int, number: Int) =
number % factor == 0
def factors(number: Int) = {
val factorsBelowSqrt = (1 to Math.sqrt(number).toInt).par.filter (isFactor(_, number))
val factorsAboveSqrt = factorsBelowSqrt.par.map(number / _)
(factorsBelowSqrt ++ factorsAboveSqrt).toList.distinct
}
def sum(factors: Seq[Int]) =
factors.par.foldLeft(0)(_ + _)
def isPerfect(number: Int) =
sum(factors(number)) - number == number
}

清單 1 中的 factors() 方法返回一個數(shù)的因數(shù)列表,使用 isFactor() 方法過濾所有可能的值。factors() 方法使用了我在 “函數(shù)式思維:轉(zhuǎn)換和優(yōu)化” 中更詳細地介紹的一種優(yōu)化。簡單來講,過濾每個數(shù)來查找因素的效率很低,因為根據(jù)定義,一個因數(shù)是其乘積等于目標(biāo)數(shù)的兩個數(shù)之一。

相反,我僅過濾不超過目標(biāo)數(shù)的平方根的數(shù),然后通過將目標(biāo)數(shù)除以每個小于平方根的因數(shù)來生成對稱因數(shù)列表。在 清單 1 中,factorsBelowSqrt 變量包含過濾操作的結(jié)果。factorsAboveSqrt 的值是現(xiàn)有列表的映射,用于生成這些對稱值。最后,factors() 的返回值是一個串聯(lián)的列表,它從一個并行的List 轉(zhuǎn)換為常規(guī)的 List。

請注意,清單 1 中添加了 par 修飾符。該修飾符會導(dǎo)致 filter、map 和 foldLeft 并行運行,從而能夠使用多個線程來處理請求。par 方法(在整個 Scala 集合庫中都是一致的)將該序列轉(zhuǎn)換為并行序列。因為兩種類型的序列反映了它們的簽名,所以 par 函數(shù)變成了并行化某個操作的臨時方式。

在 Scala 中并行化常見問題的簡單性,在語言設(shè)計和函數(shù)模式上都經(jīng)過證實。函數(shù)式編程鼓勵使用通用的函數(shù),比如 map、filter 和 reduce,運行時以不可見的方式可以進一步優(yōu)化它們。Scala 語言設(shè)計人員考慮到了這些優(yōu)化,最終產(chǎn)生了集合 API 的設(shè)計。

邊緣情況

在 清單 1 的 factors() 方法實現(xiàn)中,整數(shù)的平方根(例如,16 的平方根:4)顯示在兩個列表中。因此,factors() 方法返回的最后一行是對 distinct 函數(shù)的調(diào)用,它從列表中刪除了重復(fù)值。您也可以在每一處都使用 Set,而不是只在列表中使用它,但 List 常常擁有 Set 中所沒有的有用函數(shù)。

Groovy 也允許輕松地修改現(xiàn)有的函數(shù)代碼,通過 GPars 庫讓它并行化,該庫捆綁在各個 Groovy 發(fā)行版中。GPars 框架在內(nèi)置的 Java 并行性原語之上創(chuàng)建有用的抽象,常常將它們包裝在語法糖中。GPars 提供了令人眼花繚亂的并行機制,其中一種機制可用于分配線程池,然后將操作分布到這些池中。清單 2 中給出了一個使用 Groovy 編寫的,使用 GPars 線程池的完美數(shù)分類器。

清單 2. Groovy 中的并行完美數(shù)分類器

class NumberClassifierPar {
static def factors(number) {
GParsPool.withPool {
def factors = (1..round(sqrt(number) + 1)).findAllParallel { number % it == 0 }
(factors + factors.collectParallel { number / it }).unique()
}
}
static def sumFactors(number) {
factors(number).inject(0, { i, j -> i + j })
}
static def isPerfect(number) {
sumFactors(number) - number == number
}
}

清單 2 中的 factors() 方法使用了與 清單 1 相同的算法:它生成不超過目標(biāo)數(shù)的平方根的所有因數(shù),然后生成剩余的因數(shù)并返回串聯(lián)的集合。與 清單 1 中一樣,我使用 unique() 方法來確保整數(shù)的平方根不會生成重復(fù)值。

無需像 Scala 中一樣放大集合來創(chuàng)建對稱并行版本,Groovy 的設(shè)計人員創(chuàng)建了該語言的轉(zhuǎn)換方法的 xxxParallel() 版本(例如 findAllParallel() 和 collectParallel())。但除非這些方法包裝在 GPars 線程池代碼塊中,否則它們不會起作用。

在 清單 2 中,我創(chuàng)建了一個線程池,調(diào)用 GParsPool.withPool 創(chuàng)建一個代碼塊,支持在該代碼塊中使用 xxxParallel() 方法。withPool 方法存在其他變體。例如,您可指定池中的線程數(shù)量。

Clojure 通過 化簡器 庫提供了一種類似的臨時并行化機制。使用轉(zhuǎn)換函數(shù)的化簡器版本來實現(xiàn)自動并行化,例如,
使用 r/map 代替 map。(r/ 是化簡器命名空間。)化簡器的實現(xiàn)是 Clojure 的語法靈活性中的一個引人注目的案例分析,它通過極小的更改實現(xiàn)了強大的添加功能。

Scala 中的 actor

Scala 包含眾多并發(fā)性和并行性機制。一種較流行的機制是 actor 模型,它提供了將工作分布到線程上的優(yōu)勢,而沒有同步的復(fù)雜性。在概念上,actor 有能力完成工作,然后將一個非阻塞的結(jié)果發(fā)送給協(xié)調(diào)器。要創(chuàng)建一個 actor,需要創(chuàng)建 Actor 類的子類并實現(xiàn) act() 方法。通過使用 Scala 的語法糖,可繞過許多定義儀式,在代碼塊內(nèi)定義 actor。

我沒有為 清單 1 中的數(shù)字分類器執(zhí)行的一種優(yōu)化是,使用線程對作業(yè)的因數(shù)查找部分進行分區(qū)。如果我的計算機上有 4 個處理器,我可為每個處理器創(chuàng)建一個線程并拆分工作。例如,如果我嘗試找到數(shù)字 16 的因數(shù)之和,那么我可以安排處理器 1 來查找從 1 到 4 的因數(shù)(并求和),安排處理器 2 來處理 5 到 8,依此類推。使用 actor 是一種自然的選擇:我為每個范圍創(chuàng)建了一個 actor,獨立地執(zhí)行每個 actor(通過語法糖隱式執(zhí)行或通過調(diào)用它的 act() 方法來顯式執(zhí)行),然后收集結(jié)果,如清單 3 所示。

清單 3. 使用 Scala 中的 actor 識別完美數(shù)

object NumberClassifier extends App {
def isPerfect(candidate: Int) = {
val RANGE = 10000
val numberOFPartitions = (candidate.toDouble / RANGE).ceil.toInt
val coordinator = self
for (i <- 0 until numberOFPartitions) {
val lower = i * RANGE + 1
val upper = candidate.min((i + 1) * RANGE)
actor {
var partialSum = 0
for (j <- lower to upper)
if (candidate % j == 0) partialSum += j
coordinator ! partialSum
}
}
var responsesExpected = numberOFPartitions
var sum = 0
while (responsesExpected > 0) {
receive {
case partialSum : Int =>
responsesExpected -= 1
sum += partialSum
}
}
sum == 2 * candidate
}
}

為了保持此示例的簡單性,我將 isPerfect() 編寫為單個完整的函數(shù)。我首先基于常量 RANGE 創(chuàng)建了一些分區(qū)。其次,我需要一種方式來收集 actor 所生成的消息。在 coordinator 變量中,我有一個引用可供 actor 向其發(fā)送消息,其中 self 是 Actor 的一個成員,表示 Scala 中獲取線程標(biāo)識符的可靠方式。

我然后為分區(qū)編號創(chuàng)建一個循環(huán),使用 RANGE 偏移來生成范圍的下限和上限。接下來,為該范圍創(chuàng)建一個 actor,使用 Scala 的語法糖來避免正式的類定義。在 actor 內(nèi),我為 partialSum 創(chuàng)建了一個臨時保存器,然后分析該范圍,將找到的因數(shù)收集到 partialSum 中。收集部分和(此范圍內(nèi)的所有因數(shù)的和)后, (coordinator ! partialSum) 向協(xié)調(diào)器發(fā)回一條消息,使用感嘆號運算符。(這種消息傳遞語法的靈感來源于 Erlang 語言,用作一種對另一個線程執(zhí)行非阻塞調(diào)用的途徑。)

接下來,我啟動了一個循環(huán),等待所有 actor 完成處理。在等待過程中,我進入了一個 receive 代碼塊。在該代碼塊內(nèi),我想要一條 Int 消息,我在本地將它分配給 partialSum,然后遞減想要的響應(yīng)數(shù)量,將該部分添加到總和中。所有 actor 完成且報告結(jié)果后,該方法的最后一行將該和與候選數(shù)的 2 倍相比較。如果比較結(jié)果為 true,那么我的候選數(shù)就是一個完美數(shù),該函數(shù)的返回值為 true。

actor 的一個不錯的優(yōu)勢是所有權(quán)分區(qū)。每個 actor 都有一個 partialSum 局部變量,但它們從不彼此聯(lián)系。通過協(xié)調(diào)器收到消息時,底層執(zhí)行機制是不可見的:您創(chuàng)建了一個 receive 塊,其他實現(xiàn)細節(jié)是不可見的。

Scala 中的 actor 機制是 Java 下一代語言封裝 JVM 的現(xiàn)有工具并使用一致的抽象來擴展它們的優(yōu)秀示例。用 Java 語言編寫類似的代碼,并使用低級并發(fā)性原語,這些操作都需要非常復(fù)雜地協(xié)調(diào)多個線程。Scala 中的 actor 隱藏了所有復(fù)雜性,留下的是容易理解的抽象。

結(jié)束語

Java 下一代語言都為 Java 語言中的并發(fā)性難題提供了答案,而且每種語言以不同方式解決了這些問題。在本期文章中,我演示了所有三種 Java 下一代語言如何實現(xiàn)臨時并行化。我還演示了 Scala 中的 actor 模型,構(gòu)建了一個數(shù)字分類器來并行計算因數(shù)之和。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring?Boot異步線程間數(shù)據(jù)傳遞的四種方式

    Spring?Boot異步線程間數(shù)據(jù)傳遞的四種方式

    這篇文章主要為大家介紹了Spring?Boot異步線程間數(shù)據(jù)傳遞的四種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Java注解機制之Spring自動裝配實現(xiàn)原理詳解

    Java注解機制之Spring自動裝配實現(xiàn)原理詳解

    這篇文章主要為大家詳細介紹了Java注解機制之Spring自動裝配實現(xiàn)原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • java中ThreadLocal取不到值的兩種原因

    java中ThreadLocal取不到值的兩種原因

    這篇文章主要介紹了java中ThreadLocal取不到值的兩種原因,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SpringBoot整合TomCat實現(xiàn)本地圖片服務(wù)器代碼解析

    SpringBoot整合TomCat實現(xiàn)本地圖片服務(wù)器代碼解析

    這篇文章主要介紹了SpringBoot整合TomCat實現(xiàn)本地圖片服務(wù)器代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • springboot操作靜態(tài)資源文件的方法

    springboot操作靜態(tài)資源文件的方法

    這篇文章主要介紹了springboot操作靜態(tài)資源文件的方法,本文給大家提到了兩種方法,小編在這里比較推薦第一種方法,具體內(nèi)容詳情大家跟隨腳本之家小編一起看看吧
    2018-07-07
  • springboot集成swagger、knife4j及常用注解的使用

    springboot集成swagger、knife4j及常用注解的使用

    這篇文章主要介紹了springboot集成swagger、knife4j及常用注解的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java線程的并發(fā)工具類實現(xiàn)原理解析

    Java線程的并發(fā)工具類實現(xiàn)原理解析

    本文給大家講解Java線程的并發(fā)工具類的一些知識,通過適用場景分析大數(shù)據(jù)量統(tǒng)計類任務(wù)的實現(xiàn)原理和封裝,多個示例代碼講解的非常詳細,對java線程并發(fā)工具類相關(guān)知識感興趣的朋友一起學(xué)習(xí)下吧
    2021-06-06
  • Java中super和this關(guān)鍵字詳解

    Java中super和this關(guān)鍵字詳解

    這篇文章主要介紹了Java中super和this關(guān)鍵字詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • java郵件亂碼的徹底解決方案

    java郵件亂碼的徹底解決方案

    在本篇文章里小編給大家整理的是關(guān)于java郵件亂碼的徹底解決方案,需要的朋友們可以學(xué)習(xí)下。
    2019-12-12
  • springbatch的封裝與使用實例詳解

    springbatch的封裝與使用實例詳解

    主要實現(xiàn)批量數(shù)據(jù)的處理,我對batch進行的封裝,提出了jobBase類型,具體job需要實現(xiàn)它即可。這篇文章主要介紹了springbatch的封裝與使用 ,需要的朋友可以參考下
    2019-04-04

最新評論

万载县| 浪卡子县| 崇明县| 资中县| 繁昌县| 黄浦区| 虎林市| 甘肃省| 镇平县| 万山特区| 新闻| 阜新市| 大理市| 芜湖市| 舒城县| 元朗区| 宁远县| 天气| 二连浩特市| 永仁县| 新兴县| 精河县| 陵水| 封丘县| 田林县| 封开县| 雅安市| 阿克苏市| 黎平县| 廊坊市| 勃利县| 新昌县| 丹阳市| 隆安县| 巴青县| 奉新县| 通城县| 新和县| 宣武区| 乐亭县| 长治市|