Akka事務STM

      網友投稿 655 2025-03-31

      一個事務必須具有以下四個特點,即所謂的ACID特性:


      原子性:所有的操作要么全部成功,要么全部失敗。

      一致性:在事務完成后,系統保持一致性狀態。

      隔離性:在一個事務成功或失敗前,產生的數據對于系統中的其他事務是不見的。

      持久性:事務操作的結果要持久化保存。

      Akka使用(Software Transactional Memory)軟件事務內存來實現事務。這是一種多線程之間數據共享的同步機制。對于并行計算編程而言,只要將線程中需要 訪問共享內存的關鍵邏輯 部分劃分出來封裝到一個事務中即可。

      傳統的保護共享數據的方法就是加同步鎖。在java或Scala中以synchronized同步代碼塊的形式來實現:

      var seats = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) val reservedSeat = seats.synchronized {// seats的synchronized構建臨界區 val head = seats.head// 取出第一個元素 seats = seats.tail// 把除取出的第一個元素外的元素重新賦值給synchronized head }

      1

      2

      3

      4

      5

      6

      7

      所有的線程在synchronized塊上面是依次執行的,保證了在同一時刻只有一個線程訪問共享變量,確保了共享變量的一致性。但是如果有線程只是想去讀取共享變量,而不是要去修改時,遇到synchronized塊也是要等待的,這樣會降低了系統的整體性能,這種鎖,叫做“悲觀鎖”,這種鎖它會假設在任何時候都可能會有線程去修改共享變量。

      相應的就會有**“樂觀鎖”**,樂觀鎖認為在訪問和修改共享變量時,都不會產生任何問題。因此在執行代碼時不會有任何鎖。在樂觀鎖的實現中,當線程離開了臨界區時,系統會檢測可能的更新沖突,如果檢測不到更新沖突,那么就直接提交事務,如果檢測到有沖突發生,那么所有的改變都會回滾并嘗試重新執行臨界區代碼。

      STM使用的是樂觀鎖。Akka通過將共享變量包裝到STM的引用中,檢測共享數據在事務中是否已經發生改變,從而能防止因多線程訪問共享變量造成的數據不一致的問題。

      要使用STM必須在build.sbt中加入:

      libraryDependencies += "com.typesafe.akka" %% "akka-agent" % "2.5.23"

      1

      未例代碼:

      import concurrent.stm._ object HelloScala { def main(args: Array[String]): Unit = { // 使用Ref包裹變量 val mySeq = Seq[Int](1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) val seats = Ref(mySeq) // 在atomic塊中使用Ref變量示例 val getSeat = atomic{implicit txt => val head = seats().head// 取出第一個值 // 共享變量 seats() = seats().tail// 重新賦值 head } println(getSeat) } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      Akka的事務STM

      17

      18

      上面的seats變量,只能夠中atomic塊中使用,在atomic塊的代碼將被視為一個原子命令被執行。在編譯時,atomic塊需要一個隱式變量如上述的txt來為Ref中手沖突做檢測。上述代碼跟synchronized做的是同樣的事情,但是工作機制完全不同。STM使用的是樂觀鎖,當atomic塊執行完成后,有一個檢查將會執行,這個操作就是去檢查是否有沖突發生。ACID樂觀鎖實現了三個,沒有實現持久化,因STM都是發生在內存中,內存中的事務永遠都不會持久化。面使用synchronized的臨界區只有執行一次,使用的是悲觀鎖。

      有時候,我們只想讀取共享變量,而不做任何改變。我們就可以使用Ref.View來讀取共享變量來提高性能:

      println(seats.single.get)// 得到seats視圖,調用視圖上的get方法來獲取值 println(seats.single.get.head) println(seats.single.get)

      1

      2

      3

      讀取Agent事務中的數據

      Akka中的Agent和Actor都是基于STM來處理事務的。akka的Agent提供了一個獨立于位置的異步操作,所有對Agent的操作都是異步的。

      import akka.agent.Agent import scala.concurrent.{Future} import scala.concurrent.ExecutionContext.Implicits.global case class Seat(var a: Int) object HelloScala { def main(args: Array[String]): Unit = { val agent = Agent(50)// 創建Agent println(agent())// 使用agent()方式讀取Agent數據 println(agent.get)// 使用get()方式讀取Agent數據 agent send(888)// 使用send修改Agent的值 val future1 :Future[Int] = agent alter(_+100)// 修改Agent數據 println(future1 foreach println) } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:WPS不能運行VBA怎么辦?
      下一篇:word表格如何合并(word表格如何合并在一起)
      相關文章
      亚洲国产成人影院播放| 亚洲成A人片77777国产| 亚洲一区二区三区免费| 亚洲av永久中文无码精品| 亚洲免费福利在线视频| 亚洲av永久无码嘿嘿嘿| 亚洲av片不卡无码久久| 久久狠狠爱亚洲综合影院| 亚洲一级毛片在线观| 亚洲乱码中文论理电影| 亚洲一区二区三区不卡在线播放| 亚洲国产精品综合久久网各| 亚洲国产韩国一区二区| 亚洲国产成人综合| 亚洲午夜电影在线观看| 亚洲国产精品人久久电影| 亚洲一区在线视频| 亚洲午夜精品在线| 亚洲国产激情在线一区| 亚洲综合精品伊人久久| 涩涩色中文综合亚洲| 亚洲国产美女精品久久久| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲大成色www永久网址| 亚洲不卡中文字幕| 亚洲精品午夜国产va久久| 亚洲熟妇AV日韩熟妇在线| 亚洲AV香蕉一区区二区三区| 国产亚洲精品成人久久网站| 亚洲精品偷拍视频免费观看| 中文字幕精品亚洲无线码一区| 久久精品国产亚洲综合色| 亚洲日本一区二区| 亚洲AV综合色区无码二区偷拍| 亚洲日韩久久综合中文字幕| 日日摸日日碰夜夜爽亚洲| 亚洲日本中文字幕一区二区三区| 亚洲国产三级在线观看| 久久亚洲春色中文字幕久久久| 亚洲日本视频在线观看| 亚洲最大的成人网站|