王家林親授《DT大數據夢工廠》大數據實戰視頻 Scala 深刻淺出實戰經典(1-87講)完整視頻、PPT、代碼下載:
百度雲盤:http://pan.baidu.com/s/1c0noOt6
騰訊微雲:http://url.cn/TnGbdC
360雲盤:http://yunpan.cn/cQ4c2UALDjSKy 訪問密碼 45e2
土豆:http://www.tudou.com/programs/view/j_kmot9uBb0/
優酷:http://v.youku.com/v_show/id_XMTI5MTgwMDAxNg==.html?from=s1.8-1-1.2
愛奇藝:http://www.iqiyi.com/w_19rru5bi79.html#vfrm=2-3-0-1
騰訊視頻:http://v.qq.com/boke/page/b/0/5/b0160il3wj5.html
技術愛好者尤爲是大數據愛好者 能夠加DT大數據夢工廠的qq羣html
DT大數據夢工廠① :462923555
DT大數據夢工廠②:437123764
DT大數據夢工廠③ :418110145java
微信公衆帳號: DT_Spark
王家林老師微信號: 18610086859
王家林老師QQ: 1740415547
王家林老師郵箱: 18610086859@126.com編程
本視頻由王家林老師, 親自講解, 徹底經過代碼實戰把您帶人大數據的時代.安全
package com.parllay.scala.actor微信
/**
* Created by richard on 15-8-25.
* 第66講:Scala併發編程實戰初體驗
*/
object Hello_Actor {
/**
* Scala語言有不少優勢,好比簡潔、強大的表現力等等。但我最關注的,是它在併發編程方面的優點。多線程
Scala經過強調對象的不變性 以及使用基於事件的模型進行線程間通訊 使得實現併發應用變得簡單。併發
不變對象異步
併發編程之因此這麼困難,很大一個緣由在於對象的可變性。
要在充斥着大量可變對象的程序裏面實現安全併發,
須要很是繁瑣以及複雜易錯的同步操做來保證狀態更新的同步。編程語言
好比下面這段代碼(java的例子),可能你會認爲它已是線程安全的了,
由於全部的方法都已經被同步。大數據
Java代碼 收藏代碼
class Account {
private int balance;
synchronized public int getBalance() {
return balance;
}
synchronized public void incrementBalance() {
balance++;
}
}
可是問題來了,當順序調用這兩個方法的時候,好比:
Java代碼 收藏代碼
account.incrementBalance();
account.getBalance();
這時並非線程安全的,在第一個方法調用結束以後,
可能會被其它線程獲取對象的鎖,修改account的balance。
在命令式編程語言裏面,命令查詢分離是一個廣泛使用的原則。意即:
一個方法要麼進行一次命令(執行一個操做,一般會修改狀態),
要麼進行一次查詢(返回一些狀態, 但並不修改狀態),而不該該同時執行命令以及查詢。
從面向對象的角度看,這是一個良好的設計;但從併發編程的角度看,
它卻帶來了一些問題,使得併發編程實現更加困難。上面就是一個很好的例子。
要使得上面這段代碼變得線程安全,能夠經過破壞命令查詢分離原則來實現:
Java代碼 收藏代碼
synchronized public int incrementAndGetBalance() {
balance++;
return balance;
}
從上面的例子看到,在可變對象的環境中實現併發編程是困難的。而不變對象,
意即線程安全的對象,使得咱們沒必要擔憂共享對象會被多個線程同時修改而沒法保持它的正確性:
由於它自己就不可修改。咱們能夠把不變對象很放心地扔到多線程環境中,任意使用。
問題又來了,若是要「修改狀態」怎麼辦?很簡單,建立一個新的對象。仍是上面那個例子,
咱們把它修改爲一個Scala的不變對象類。並在伴生對象裏面實現increment方法,
此方法會返回一個新的account對象,balance值爲原有對象的值加1所得。
Java代碼 收藏代碼
class Account (val balance: Integer) {
def getBalance() = balance
}
object Account {
def increment(account: Account): Account {
new Account(account.getBalance() + 1)
}
}
經過強調不變對象的使用,併發編程變得簡單了不少。
Actor
傳統的併發是經過線程(thread)來實現的。在傳統的併發模型中,程序被分紅若干份同時執行的任務,
而且全部任務都對一塊共享的內存進行操做。在傳統的併發模型會引發競爭問題,
能夠採起鎖機制避免競爭問題,但同時這可能帶來死鎖等問題。
Actor模型是另外一種不一樣的併發模型,它很好地解決了在傳統併發模型中競爭和死鎖等問題。
咱們能夠把一個由actor模型實現的併發程序當作是一個星系同樣,星系裏面有不少星球,
每一個星球都是一個actor,星球之間不共享任何資源,可是它們之間有通道來相互傳遞信息。
每一個星球(actor)都有一個信箱來接受來自其它星球的任意信息,它會按照信息接收的順序來處理,
處理完一個信息而後接着處理下一個信息。能夠按照信息類型來觸發不一樣的行爲。
同時,每一個星球(actor)能夠異步地(也能夠同步,但不是這裏談論的重點)向其它任意星球發送任意消息,
就是說,它發送消息以後不會等待返回信息而是直接執行接下來的操做。
下面是一個Actor的例子:
Java代碼 收藏代碼
import scala.actors.Actor
import scala.actors.Actor._
case class Increment(amount: Int)
case class Balance
class Account extends Actor {
var balance: Int = 0;
def act() = {
while (true) {
receive {
case Increment(amount) =>
balance += amount
case Balance =>
println("Balance is " + balance)
exit()
}
}
}
}
咱們能夠看到,程序裏面定義兩種不一樣的消息類型:Increment和Balance。Account是一個Actor,
它跟外界的交互都是經過消息傳遞來實現:不管是increment,仍是獲取balance都是經過消息的方式來實現。
當接受到不一樣的消息時,它會執行不一樣的行爲。
咱們也能夠看到,Account的內部狀態徹底是本身控制的,接收到的消息是順序執行的,
因此咱們不須要擔憂競爭問題。
小結
Scala就是這樣,經過「使用基於事件的模型進行線程間通訊」,而且「把不變對象做爲消息進行傳遞」來實現一個併發編程模型。 */}