[concurrency-interest] syntax sugar for lazy instantiation

Ashley Williams ashpublic at mac.com
Tue Jun 23 14:38:44 EDT 2009


I'm going to have to think about this one since I've used futures but  
never connected them to double checked locks.
Fo instance I want to check that:

- I get fast access to field  99% of the time
- I only pay for lock when initializing a field.

I'm sure there are a ton of tricks like this, what would be great is  
an "effective threading" book for those that have
read the theory and want to get straight to idioms.

On 23 Jun 2009, at 19:19, Ben Manes wrote:

> I use this trick all the time, but its already supplied via  
> FutureTask.  It has very similar semantics to your code.  This trick  
> can be extended to build lazy maps (and other lazy structures) which  
> is also very convenient.
>
> public class Example {
>     private final FutureTask<Computation> future = new  
> FutureTask<Computation>(new Computable());
>
>     // Lazily computes the work and returns the value
>     public Computation getComputation() throws Exception {
>         future.run(); // no-ops on all subsequent calls
>         return future.get();
>     }
>
>     private static final class Computable implements  
> Callable<Computation> {
>         public Computation call() {
>           // do work, return
>         }
>     }
> }
>
> From: Ashley Williams <ashpublic at mac.com>
> To: concurrency-interest at cs.oswego.edu
> Sent: Tuesday, June 23, 2009 10:05:24 AM
> Subject: [concurrency-interest] syntax sugar for lazy instantiation
>
> It seems to me that the only reason to use an intrinsic lock on a  
> lazy getter (stick a synchronized keyword
> on the method signature) is convenience of syntax. Please correct me  
> if I am wrong.
>
> So is one idea to simplify lazy instantiation, feedback welcome if  
> anybody can improve on it. It's based
> on the observation that double checked locking is mostly boilerplate  
> except for the line that creates
> the instance and so I've factored it out into a callable interface.
>
> Admittedly the anonymous class makes for a more verbose constructor,  
> but at least the dcl logic is
> now encapsulated. And if java had support for closures then the  
> readability problem would go away.
>
> So first the class:
>
> @ThreadSafe
> public final class LazyField<T> {
> 	private volatile T obj;
> 	private final Callable<T> callable;
>
> 	public LazyField(Callable<T> callable) {
> 		this.callable = callable;
> 	}
>
> 	public T get() {
> 		if (obj == null) {
> 			synchronized (this) {
> 				if (obj == null) {
> 					obj = callable.call();
> 				}
> 			}
> 		}
> 		return obj;
> 	}
> }
>
> and here is an example usage:
>
> @ThreadSafe
> public final class MyClass {
> 	private final LazyField<String> message;
>
> 	public MyClass() {
> 		this.message = new LazyField<String>(new Callable<String>() {
> 			public String call() throws Exception {
> 				return "hello world";
> 			}
> 		});
> 	}
>
> 	public String getMessage() {
> 		return message.get();
> 	}
> }
>
> - Ashley Williams
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20090623/5a2e7504/attachment-0001.html>


More information about the Concurrency-interest mailing list