This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Implementation of lazy val within an object's method

4 replies
Vladimir Sorokin
Joined: 2011-10-05,
User offline. Last seen 1 week 6 days ago.

Hi.

I have recently faced a strange thread blocking issue. Sorry if this
issue has been already discussed before, I couldn't find it.
Let's say we have this object:
object Test {
def func() {
lazy val a = someExpensiveCalculations
// now we use (or not) this lazy val, for example:
println(a)
}
private def someExpensiveCalculations = 1
}

Scala compiler creates this code (after decompilation):
public final class Test$ implements ScalaObject {
public void func() {
IntRef a$lzy$1 = new IntRef(0);
VolatileIntRef bitmap$0$1 = new VolatileIntRef(0);
Predef$.MODULE$.println(BoxesRunTime.boxToInteger(a$1(a$lzy$1,
bitmap$0$1)));
}

private final int a$1(IntRef intref, VolatileIntRef
volatileintref)
{
if((volatileintref.elem & 1) == 0)
synchronized(this)
{
if((volatileintref.elem & 1) == 0)
{
intref.elem = someExpensiveCalculations();
volatileintref.elem = volatileintref.elem | 1;
}
BoxedUnit _tmp = BoxedUnit.UNIT;
}
return intref.elem;
}
// other unimportant stuff
}

The main part here is "synchronized(this)".
It means that if I call Test.func() from many concurrent threads, It
will lead to blocking, because they all use one monitor.
For me, this is very strange, because "val a" is a local variable of
method func(), and each call of this method will create a new instance
of a, and all these instances are absolutely independent.
Therefore I think it should use other object for synchronization
(unique for each call of func()), not singleton Test, because current
implementation leads to huge synchronization overhead in highly
concurrent systems.

Hubert Plociniczak
Joined: 2009-09-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Implementation of lazy val within an object's method

Hi,

it looks like the tree generator for double checked locking always
followed this template (i.e. synchronize on the enclosing class).
Not sure if there is a deeper reason for that or did we just follow java
implementation exactly and forgot about it. Please create a bug, I will
have a look.

hubert

On 10/05/2011 04:42 PM, Vladimir Sorokin wrote:
> Hi.
>
> I have recently faced a strange thread blocking issue. Sorry if this
> issue has been already discussed before, I couldn't find it.
> Let's say we have this object:
> object Test {
> def func() {
> lazy val a = someExpensiveCalculations
> // now we use (or not) this lazy val, for example:
> println(a)
> }
> private def someExpensiveCalculations = 1
> }
>
> Scala compiler creates this code (after decompilation):
> public final class Test$ implements ScalaObject {
> public void func() {
> IntRef a$lzy$1 = new IntRef(0);
> VolatileIntRef bitmap$0$1 = new VolatileIntRef(0);
> Predef$.MODULE$.println(BoxesRunTime.boxToInteger(a$1(a$lzy$1,
> bitmap$0$1)));
> }
>
> private final int a$1(IntRef intref, VolatileIntRef
> volatileintref)
> {
> if((volatileintref.elem& 1) == 0)
> synchronized(this)
> {
> if((volatileintref.elem& 1) == 0)
> {
> intref.elem = someExpensiveCalculations();
> volatileintref.elem = volatileintref.elem | 1;
> }
> BoxedUnit _tmp = BoxedUnit.UNIT;
> }
> return intref.elem;
> }
> // other unimportant stuff
> }
>
> The main part here is "synchronized(this)".
> It means that if I call Test.func() from many concurrent threads, It
> will lead to blocking, because they all use one monitor.
> For me, this is very strange, because "val a" is a local variable of
> method func(), and each call of this method will create a new instance
> of a, and all these instances are absolutely independent.
> Therefore I think it should use other object for synchronization
> (unique for each call of func()), not singleton Test, because current
> implementation leads to huge synchronization overhead in highly
> concurrent systems.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Implementation of lazy val within an object's method

On Wed, Oct 5, 2011 at 8:23 AM, Hubert Plociniczak
wrote:
> it looks like the tree generator for double checked locking always followed
> this template (i.e. synchronize on the enclosing class).
> Not sure if there is a deeper reason for that or did we just follow java
> implementation exactly and forgot about it. Please create a bug, I will have
> a look.

There are already multiple tickets open, which look pretty combinable.

https://issues.scala-lang.org/browse/SUGGEST-8
https://issues.scala-lang.org/browse/SUGGEST-11

Vladimir Sorokin
Joined: 2011-10-05,
User offline. Last seen 1 week 6 days ago.
Re: Implementation of lazy val within an object's method

Hi Hubert, Paul.

Thanks for your replies.
Yes, those tickets describe the same problem.

Vladimir.

On Oct 5, 8:11 pm, Paul Phillips wrote:
> On Wed, Oct 5, 2011 at 8:23 AM, Hubert Plociniczak
>
> wrote:
> > it looks like the tree generator for double checked locking always followed
> > this template (i.e. synchronize on the enclosing class).
> > Not sure if there is a deeper reason for that or did we just follow java
> > implementation exactly and forgot about it. Please create a bug, I will have
> > a look.
>
> There are already multiple tickets open, which look pretty combinable.
>
>  https://issues.scala-lang.org/browse/SUGGEST-8
>  https://issues.scala-lang.org/browse/SUGGEST-11

Hubert Plociniczak
Joined: 2009-09-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Implementation of lazy val within an object's method

On 10/05/2011 06:11 PM, Paul Phillips wrote:
> On Wed, Oct 5, 2011 at 8:23 AM, Hubert Plociniczak
> wrote:
>> it looks like the tree generator for double checked locking always followed
>> this template (i.e. synchronize on the enclosing class).
>> Not sure if there is a deeper reason for that or did we just follow java
>> implementation exactly and forgot about it. Please create a bug, I will have
>> a look.
> There are already multiple tickets open, which look pretty combinable.
>
> https://issues.scala-lang.org/browse/SUGGEST-8
> https://issues.scala-lang.org/browse/SUGGEST-11

Good to know. I didn't have them on my radar.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland