-
Notifications
You must be signed in to change notification settings - Fork 14
Closed
Milestone
Description
Welcome to Scala 2.11.8
Type in expressions for evaluation. Or try :help.
scala> class C { def foo = { object O { assert(Thread.holdsLock(C.this)) }; O }}; new C().foo
defined class C
res0: AnyRef = C$O$2$@3ada9e37
scala> class C { def foo = { lazy val O = { assert(Thread.holdsLock(C.this)) }; O }}; new C().foo
defined class C
In 2.12 / scala/scala#5294, the latter changed:
the locking scope of a local lazy val is now tied to the lazy val, following Dotty's encoding
Welcome to Scala 2.12.0-...
scala> class C { def foo = { lazy val O = { assert(Thread.holdsLock(C.this)) }; O }}; new C().foo
java.lang.AssertionError: assertion failed
This change was motivated by a variation of the programs above, in which the lazy val was enclosed in a lambda. In 2.11, the enclosing this
that we locked on during lazy val init was the anon function class. In 2.12, it became the source-level enclosing class of the lambda. This introduced a class of deadlocks to previously working code, so it seemed like the right time to moving to finer grained locks.
However, we have not made a corresponding change for method-local modules:
Welcome to Scala 2.12.0-...
scala> class C { def foo = { object O { assert(Thread.holdsLock(C.this)) }; O }}; new C().foo
defined class C
res0: AnyRef = C$O$2$@746b18fd
Metadata
Metadata
Labels
No labels