Skip to content

Instantly share code, notes, and snippets.

@ms-tg
Created January 24, 2012 17:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ms-tg/1671423 to your computer and use it in GitHub Desktop.
Save ms-tg/1671423 to your computer and use it in GitHub Desktop.
Scala 'lazy val' vs Java memoization
/**
* Without worrying about concurrency, we can simply cache the return value,
* using null to indicate that it has not yet been calculated...
*/
public class Memoize1 extends Original {
private Integer total;
@Override
public int total() {
if (total == null) {
total = super.total();
}
return total;
}
}
/**
* Makes this safe for concurrency -- all calls synchronized -- but this
* is unnecessarily slow if calling frequently...
*/
public class Memoize2 extends Original {
private Integer total;
@Override
public int total() {
synchronized(this) {
if (total == null) {
total = super.total();
}
}
return total;
}
}
/**
* The so called "double check" pattern:
* safe for concurrency, and fast
*/
public class Memoize3 extends Original {
private Integer total;
@Override
public int total() {
if (total == null) {
synchronized(this) {
if (total == null) {
total = super.total();
}
}
}
return total;
}
}
/**
* Say we have a method which always returns the same calculation...
*/
public class Original {
public int total() {
return 1+1; // potentially expensive calculation here
}
}
/**
* So what does Scala generate for this?
*/
class ScalaLazy {
lazy val total = 1+1
}
/**
* Approximate decompilation of Scala lazy val,
* see http://code-o-matic.blogspot.com/2009/05/double-checked-locking-idiom-sweet-in.html
*/
public class ScalaLazy {
public volatile int bitmap$0;
private int total;
public int total() {
if ((bitmap$0 & 1) == 0) {
synchronized(this) {
if ((bitmap$0 & 1) == 0) {
total = 1+1; // here's the expensive calculation
bitmap$0 = bitmap$0 | 1;
}
}
}
return total;
}
}
@mlc
Copy link

mlc commented Jun 21, 2013

your 'memoize3.java' isn't fully threadsafe unless the total field is declared volatile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment