Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该在Scala中同步哪个对象?_Java_Multithreading_Scala - Fatal编程技术网

Java 我应该在Scala中同步哪个对象?

Java 我应该在Scala中同步哪个对象?,java,multithreading,scala,Java,Multithreading,Scala,在C#中,这非常简单: class Class1{ private static readonly object locker = new object(); void Method1(){ lock(locker) { .... } } } 我绝对不应该对这个进行同步,因为这可能会导致死锁。类似地,在Scala中,我看到了一些示例,但无法理解同步的基本原理以及我应该使用的对象(字段)来进行同步: #1 def add(user: User) { // tokenize

在C#中,这非常简单:

class Class1{
  private static readonly object locker = new object();
  void Method1(){
    lock(locker) { .... }
  }
}
我绝对不应该对
这个
进行同步,因为这可能会导致死锁。类似地,在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中锁定对象与在Java中锁定静态字段/类是一样的,这基本上是“最难”的锁定之一。它不会阻止类实例上的操作,而是阻止类加载器范围内的类本身上的操作。在引入这样的锁时,您应该仔细考虑。它不会保护您免受由于获取的锁的顺序不正确而导致的死锁的影响,但是如果线程正在处理一个类的不同实例,则会导致阻塞线程,并且可能根本不会产生干扰

  • 锁定“this”或某个类(非对象)字段(互斥)是一种更轻松的同步方式,您应该使用它来管理对该类的访问,而不是对该类的特定实例的访问

  • 看一看电影中的演员,他们摇摆不定,消除了许多同步方面的问题


  • 旁注:对“this”进行同步并不意味着死锁。

    在Scala中,获得相同的行为更为简单(我假设您出于某种原因希望锁定包含的对象,例如,比锁定该类的整个实例更细粒度的控制):

    但你不应该以这种方式控制事情。特别是,如果不注意
    ,它将无法防止C#或Scala中的死锁


    您至少应该使用
    java.util.concurrent
    中的并发工具,并且您可能希望了解未来或参与者。

    如果前提是您希望避免锁定
    ,因为另一个具有第三方代码的线程可以锁定同一对象,那么Scala提供了更高级别的可见性
    私有[这]

    class C {
      private[this] val lock = new Object()
      def method1(): Unit = lock.synchronized {
        println("method1")
      }
    }
    

    实际上,除了
    C
    的特定实例之外,没有其他对象可以访问
    lock
    。即使来自同一类的其他实例也无法访问
    lock
    在“this”上进行同步并不意味着死锁。
    在Java中?在C中可能是这样。我不确定如何在类I上进行同步nstance单独会导致死锁。如果您在线程B中锁定实例A,然后尝试锁定实例C,在线程D中锁定实例C并尝试锁定实例A,那么不管对象A和C是什么(静态还是非静态),您都会遇到麻烦.对“this”进行同步并不意味着死锁。--在Java中?在C中,这可能是肯定的。我认为#1中的单词选择不仔细(即,错误).Scala对象类似于Java静态,但它只是一个普通的引擎盖下的实例,一个类似Foo$.MODULE$.Foo.synchronized的静态字段意味着在该实例上进行同步,而不是在Foo$.class上进行同步。我不知道C#,但在
    上进行同步这
    不会自动在Java或Scala.I中引入死锁风险t取决于您对它们所做的操作当另一个线程在实例B和实例A上进行同步时,您就遇到麻烦了。虽然在scala中可以进行同步,但消除对它的需要会更为习惯。例如,使用不可变的数据结构,并以允许非阻塞异步执行的方式设计程序。@Romptroll,我对它很好奇。您可以吗请给我举个例子?但尽管如此,即使使用不可变的数据结构也只是将同步的责任进一步转移,例如,对于将使用不可变状态的代码的人,最终也将有必要使用它。据我所知,即使使用
    synchronized
    方法,也无法避免使用
    synchronized
    方法当只有不可变的数据结构时。不是吗?如果你的程序没有分叉,为什么你需要
    同步的
    ?如果你的子例程都基于不可变的结构,唯一可以看到状态更新的地方就是你的主方法。你可以完美地设计大型库,而不需要引入一个
    系统nchronized
    关键字。@Grienders,不,完全可能。如果您的数据完全不可变(没有例外;这也意味着没有执行I/O操作),则实际上不需要显式同步,因为没有线程能够以任何方式干扰其他线程操作。但是,对于不可变数据,线程之间传输数据的唯一方法是使用新数据段启动新的子线程。这可能非常不方便且无效,因此最终您只需具有可变状态。但是不同的库尝试抽象此状态,因此您不会直接访问它,因此您仍然不需要
    同步
    。例如,这就是actor库(例如Akka)的功能在较低的级别上,每个参与者都有可变的消息队列,但您不直接访问它,而是使用不可变的消息。因此,您的代码中没有同步的消息。@Grienders这是Scala,而且确实是创建私有锁的正确方法,它减少了死锁的风险,因为
    Class1
    完全控制了死锁的位置使用了锁。如果您只有一个私有锁,则不会陷入死锁。对于潜在的死锁,您至少需要两个锁。@Grienders-这就是Scala。您说过“在C中,这非常简单”。我更简单地演示了如何在Scala中执行完全相同的操作。因此,如果您已经知道如何在C#中执行此操作,那么现在您就知道如何在Scala中执行此操作。@0#-您确实需要至少两个锁,但它们可以是同一类的不同实例上的两个锁。因此,即使使用单个私有锁,您也必须非常小心。T
    class C {
      private[this] val lock = new Object()
      def method1(): Unit = lock.synchronized {
        println("method1")
      }
    }