You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中synchronized块锁定范围及方法阻塞问题咨询

解答Scala synchronized相关的两个问题

问题1:Scala里的synchronized块会锁定块内访问的所有全局变量吗?

当然不会。Scala的synchronized和Java的实现逻辑一致,它锁定的是当前类实例的监视器锁(也就是this对象的锁),而不是块里操作的那些变量本身。

举个例子,你代码里的synchronized块同时操作了globalOne和globalTwo,但线程进入这个块时,只需要获取当前MyClass实例的锁就行——不管你在块里操作多少变量,锁的粒度都是整个对象,不是单个变量。

问题2:执行dosync方法时,getKey会因为访问同一全局变量被阻塞吗?

不会被阻塞。因为getKey方法没有任何同步修饰或者synchronized块,当一个线程拿着MyClass实例的锁执行dosync里的同步逻辑时,另一个线程可以直接调用getKey读取globalOne,完全不会被卡住。

不过这里要提个醒:这种写法有线程安全风险。虽然globalOne是不可变的HashMap,但它被存在var里——dosync的赋值操作是原子的,但没有同步的话,其他线程可能看不到globalOne的最新值(Java内存模型的可见性问题)。如果要保证多线程下的正确性,要么给getKey也加上synchronized,要么用@volatile修饰globalOne和globalTwo,或者直接换成线程安全的可变集合比如java.util.concurrent.ConcurrentHashMap。

你的代码示例

import scala.collection.immutable.HashMap
class MyClass {
  var globalOne = HashMap[String, String]()
  var globalTwo = HashMap[String, String]()
  def dosync(k:String, v:String) = {
    synchronized {
      globalOne = globalOne.updated(k, v)
      globalTwo = globalTwo.updated(k, v)
    }
  }
  def getKey(k:String) = {
    globalOne.get(k)
  }
}

内容的提问来源于stack exchange,提问作者N A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:54:45