【发布时间】:2013-06-12 08:53:39
【问题描述】:
在 C# 中非常简单:
class Class1{
private static readonly object locker = new object();
void Method1(){
lock(locker) { .... }
}
}
我绝对不应该在this 上进行同步,因为这可能会导致死锁。同样,在 Scala 中,我看到了一些示例,但无法理解同步的基本原理和我应该用来进行同步的对象(字段):
#1
def add(user: User) {
// tokenizeName was measured to be the most expensive operation.
val tokens = tokenizeName(user.name)
tokens.foreach { term =>
userMap.synchronized {
add(term, user)
}
}
}
#2
class Person(var name: String) {
def set(changedName: String) {
this.synchronized {
name = changedName
}
}
}
#3 and so on...
你介意我说清楚吗?
【问题讨论】:
-
虽然在 scala 中可以进行同步,但消除对它的需要会更符合习惯。例如,使用不可变数据结构并以允许非阻塞异步执行的方式设计程序。
-
@rompetroll,我很好奇。你能给我举个例子吗?但尽管如此,即使使用不可变数据结构也只是将同步的责任进一步转移,例如,对于将使用具有不可变状态的代码的人,最终将有必要使用它。据我了解,即使存在 only 不可变数据结构,也无法避免使用
synchronized方法。不是这样吗? -
如果你的程序没有分叉,你为什么需要
synchronized?如果您的子例程都基于不可变结构,那么唯一可以看到状态更新的地方就是您的 main 方法。您可以完美地设计大型库,而无需引入单个synchronized关键字。 -
@Grienders,不,完全有可能。如果您的数据完全不可变(no 例外;这也意味着没有执行 I/O 操作),那么实际上不需要显式同步,因为没有线程将能够以任何方式干扰其他线程操作。
-
但是,使用不可变数据,您可以在线程之间传输数据的唯一方法是使用新数据启动新的子线程。这可能非常不方便且无效,因此您最终只需要具有可变状态即可。但是不同的库试图抽象这个状态,所以你不会直接访问它,所以你仍然不需要
synchronized。例如,这就是演员库(例如 Akka)所做的。在较低级别上,每个参与者都有 可变队列 消息,但您不能直接访问它,而是使用 不可变消息。因此,您的代码中没有synchronized。
标签: java multithreading scala