每当我读到在Scala中使用synchronized
时,作者通常会提到应该使用Actors(例如this)。虽然我大致了解演员是如何工作的,但我真的很想看到Actors的一个例子用于替换Java的synchronized
方法修饰符(我的意思是它的Scala等价物 - synchronized
块)代码例如,修改数据结构的内部结构会很高兴。
这是演员的好用还是被误导了?
答案 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 ---这里有一些明显的问题,让我们快速看一下:
scala如何修改此范例?
这些封装了这样一种期望:很快,你希望演员做的“事情”就会完成。 scala“future”取代了这个java构造:它“明确”了这样一个事实:我的while循环是“期待”在不久的将来发生的事情,之后还有一个动作要做。
虽然我正在“等待”(在上面的while循环中)完成,但显然另一种实现方式是,如果计算对象只是“告诉我”它何时完成。消息传递实现了这一点,但有些复杂,并导致在某些Java实现中无法访问,不可读的代码。由于scala以直接设计用于容纳并发工作负载的方式抽象出这一概念,现在可以以不过于复杂的方式实现消息传递设计模式,从而将“等待”逻辑与逻辑分离处理。
3)简短的回答:一般来说,scala API是为了在更高的抽象级别对并发逻辑进行编码而构建的,因此并发代码是声明性的,而不是在实现细节中混淆 强>
4)同步:一个较低级别的概念,虽然必不可少,但可能会使我们的代码复杂化。
同步是低级多线程编程的工件。通过提供最常见的并行编程范例的更高级抽象,Scala使许多最常见的并发编程用户案例中不需要这个特定的构造。事实上,现在,甚至java都这样做:) java.util.concurrent包为我们提供了原子数据类型和数据结构,避免了在“synchronized”块中包装简单操作的需要。但是,标准Java不支持“Actors”和“Futures”的更高级别概念,可以有效地管理和协调,而无需手动管理同步方法调用或对象修改。
答案 1 :(得分:4)
Actors保证每次只处理一条消息,这样就不会有两个线程访问任何实例成员 - ergo不需要使用synchronized