使用Actors而不是`synchronized`

时间:2011-11-21 17:26:28

标签: java scala programming-languages concurrency actor

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

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

2 个答案:

答案 0 :(得分:7)

1)概述

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

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

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

要使用Scala的更高级别并发模型直接替换此类代码,请查看此帖子:Scala program exiting before the execution and completion of all Scala Actor messages being sent. How to stop this?

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

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

scala如何修改此范例?

  • Scala演员可以返回“期货”

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

  • Scala演员可以传递“消息”

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

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

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

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

答案 1 :(得分:4)

Actors保证每次只处理一条消息,这样就不会有两个线程访问任何实例成员 - ergo不需要使用synchronized