Scala與Golang的併發實現對比

2022-07-27 10:06:12 字數 2400 閱讀 9073

一. scala與golang的併發實現思路

scala語言併發設計採用actor模型,借鑑了erlang的actor實現,並且在scala 2.10之後,scala採用的是akka actor模型庫。actor模型主要特徵如下:

「一切皆是參與者」,且各個actor間是獨立的;

傳送者與已傳送訊息間解耦,這是actor模型顯著特點,據此實現非同步通訊;

actor是封裝狀態和行為的物件,通過訊息交換進行相互通訊,交換的訊息存放在接收方的郵箱中;

actor可以有父子關係,父actor可以監管子actor,子actor唯一的監管者就是父actor;

乙個actor就是乙個容器,它包含了狀態、行為、乙個郵箱(郵箱用來接受訊息)、子actor和乙個監管策略;

go語言也能夠實現傳統的共享記憶體的通訊方式,但go更提倡「以通訊來共享記憶體,而非以共享記憶體來通訊」。go的併發通訊方式借鑑csp(communicating sequential process)模型,其主要特徵如下:

goroutine(協程,go的輕量級執行緒)是go的輕量級執行緒管理機制,用「go」啟動乙個goroutine, 如果當前執行緒阻塞則分配乙個空閒執行緒,如果沒有空閒執行緒,則新建乙個執行緒;

通過管道(channel)來存放訊息,channel在goroutine之間傳遞訊息;比如通過讀取channel裡的訊息(通俗點說好比乙個個「值」),你能夠明白某個goroutine裡的任務完成以否;

go給channel做了增強,可帶快取。

scala與go在併發通訊模型實現上的主要差異如下:

actor是非同步的,因為傳送者與已傳送訊息間實現了解耦;而channel則是某種意義上的同步,比如channel的讀寫是有關係的,期間會依賴對方來決定是否阻塞自己;

actor是乙個容器,使用actorof來建立actor例項時,也就意味著需指定具體actor例項,即指定哪個actor在執行任務,該actor必然要有「身份」標識,否則怎麼指定呢?!而channel通常是匿名的, 任務放進channel之後你不用關心是哪個channel在執行任務;

二. 例項說明

我們來看乙個例子:對一組連續序列(1-10000)的整數值進行累加,分別觀察scala與go環境下單執行緒與多執行緒效率,一方面了解併發效率的提公升;一方面也能夠對比scala與go併發實現的差異 ── 這才是本文的重點。具體要求如下:

對1 - 10000的整數進行累加,在併發條件下,我們將1 - 10000平均劃分為四部分,啟動四個執行緒進行併發計算,之後將四個執行緒的執行結果相加得出最終的累加統計值。為了更明顯地觀察到時間上的差異性,在每部分的每次計算過程中,我們新增乙個3000000次的空迴圈:)

三. scala實現

以下先列出scala akka actor併發實現的完整示例**:

// akka併發計算例項

import akka.actor.actor

import akka.actor.props

import akka.actor.actorsystem

import akka.routing.roundrobinpool

// 定義乙個case類

sealed trait sumtrait

case class result(value: int) extends sumtrait

// 計算用的actor

class sumactor extends actor

cal += i

}println("flag : " + flag + ".")

return cal

} def receive = }

// 列印結果用的actor

class printactor extends actor }

// 主actor,傳送計算指令給sumactor,傳送列印指令給printactor

class masteractor extends actor {

var sum = 0

var count = 0

var starttime: long = 0

// 宣告actor例項,nrofinstances是pool裡所啟routee(sumactor)的數量,

// 這裡用4個sumactor來同時計算,很powerful。

val sumactor = context.actorof(props[sumactor]

.withrouter(roundrobinpool(nrofinstances = 4)), name = "sumactor")

val printactor = context.actorof(

Golang的併發安全

channel是go中代替共享記憶體的通訊方式,channel從底層實現上是一種佇列,在使用的時候需要通道的傳送方和接收方需要知道資料型別和具體通道。如果有一端沒有準備好或訊息沒有被處理會阻塞當前端。actor模型 在actor模型中,主角是actor,類似一種worker,actor彼此之間直接傳...

golang 序列與並行(併發)對比

golang對比其它語言最大的優勢就是乙個go關鍵字就能實現併發,工作中經常遇到併發的場景,具體實現併發的方式有多種,今天就來做個小實驗來對比說明序列和並行執行任務中併發的優勢,好了直接上 package main import fmt math rand sync time 定義任務數量 var ...

golang 閒談併發

對於併發這個概念,我想大家都對它不會陌生,今天就從簡單的火車站賣票問題出發,來談談併發。首先宣告本文的 是golang 因為最近開始用的就是golang 對於其他的語言其實也是相通的,那麼正式開始正題吧,首先我們來看看,賣一張票,總票數就減一,一般來說我們會這麼寫 package main impo...