使用Actors而不是`synchronized`

sea*_*owg 16 java concurrency programming-languages scala actor

每当我读到关于使用synchronizedScala的作者通常提的是演员,而应使用(举例).虽然我大致了解演员是如何工作的,但我真的很想看到Actors的一个例子用于替换Java的synchronized方法修饰符(我的意思是它的Scala等价物 - synchronized块)在一段代码中.例如,修改数据结构的内部结构会很高兴.

这是演员的好用还是被误导了?

jay*_*100 8

1)概述

Scala Actors可以替代标准Java线程应用程序中的复杂业务逻辑,这些应用程序通常会躲避在复杂多线程系统上工作的开发人员.

考虑以下可能在一个简单的线程应用程序中看到的java代码片段(此代码正在等待异步请求完成).

myAsyncRequest.startCalculation(); 
while(notDone)
   myAsyncRequest.checkIfDone();
   Thread.sleep(1000); 
System.out.println("Done ! Value is : " + myAsyncRequest.getCalculationValue());
Run Code Online (Sandbox Code Playgroud)

要使用Scala的更高级别并发模型直接替换此类代码,请查看此帖子:Scala程序在执行和完成所有正在发送的Scala Actor消息之前退出.怎么阻止这个?

2)现在:回到代码snpipet ---这里有一些明显的问题,让我们快速看一下:

  • 该代码将"监视"计算执行的逻辑与计算结果的处理相结合.
  • 代码中嵌入了启发式(Thread.sleep(1000)),它没有明确的逻辑证明(为什么要等一秒?为什么不等待3秒?),从而为代码块添加了不必要的逻辑.
  • 它没有扩展 - 如果我运行1000个客户端,并且每个客户端都在不断检查结果,我可能会产生一些非常难看的流量 - 这是没有充分理由的.

scala如何修改这个范例?

  • 斯卡拉演员可以回归"未来"

这些封装了这样的期望:很快,你想要一个演员所做的"事情"就会完成.scala"future"取代了这个java构造:它"明确"了这样一个事实:我的while循环是"期待"在不久的将来发生的事情,并且之后还有一个动作要做.

  • Scala演员可以传递"消息"

虽然我正在"等待"(在上面的while循环中)完成,但显然另一种实现方式是,如果计算对象只是"告诉我"它何时完成.消息传递实现了这一点,但有些复杂,并导致在某些Java实现中无法访问,不可读的代码.由于scala以直接设计用于容纳并发工作负载的方式抽象出这一概念,现在可以以不过于复杂的方式实现消息传递设计模式,从而将"等待"的逻辑与逻辑分离处理.

3)简短的回答:一般来说,scala API是为了在更高的抽象级别编码并发逻辑而构建的,因此并发代码是声明性的,而不是在实现细节中混淆.

4)同步:一个较低级别的概念,虽然必不可少,但可能使我们的代码复杂化.

同步是低级多线程编程的工件.通过提供最常见的并行编程范例的更高级抽象,Scala使许多最常见的并发编程用户案例中不需要这个特定的构造.事实上,现在,甚至java都这样做:) java.util.concurrent包为我们提供了原子数据类型和数据结构,避免了在"synchronized"块中包装简单操作的需​​要.但是,标准Java不支持"Actors"和"Futures"的更高级别概念,这些概念可以有效地管理和协调,而无需手动管理同步方法调用或对象修改.

  • 这是对Actors的一个很好的解释,但它并没有真正讨论它们取消`synchronized`关键字的能力. (3认同)

Arn*_*-Oz 5

Actor 保证一次只会处理一条消息,这样就不会有两个线程访问任何实例成员 - 因此不需要使用同步