惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园 - 曹振华

移动营业厅推广 DolphinScheduler2.0.1 源码 招聘java工程师 Apache seaTunnel 数据集成平台 Spark RDD解密 Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解 Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式 Scala 深入浅出实战经典 第78讲:Type与Class实战详解 Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战 Scala 深入浅出实战经典 第76讲:模式匹配下的赋值语句 Scala 深入浅出实战经典 第75讲:模式匹配下的For循环 Scala 深入浅出实战经典 第68讲:Scala并发编程原生线程Actor、Cass Class下的消息传递和偏函数实战解析 Scala 深入浅出实战经典 第67讲:Scala并发编程匿名Actor、消息传递、偏函数解析 Scala 深入浅出实战经典 第65讲:Scala中隐式转换内幕揭秘、最佳实践及其在Spark中的应用源码解析 Scala 深入浅出实战经典 第64讲:Scala中隐式对象代码实战详解 Scala 深入浅出实战经典 第63讲:Scala中隐式类代码实战详解 Scala 深入浅出实战经典 第62讲:Scala中上下文界定内幕中的隐式参数实战详解 Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析 Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析
Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验
曹振华 · 2015-08-27 · via 博客园 - 曹振华

王家林亲授《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群

DT大数据梦工厂① :462923555
DT大数据梦工厂②:437123764
DT大数据梦工厂③ :418110145

微信公众账号: 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就是这样,通过“使用基于事件的模型进行线程间通信”,并且“把不变对象作为消息进行传递”来实现一个并发编程模型。
*/
}