[concurrency-interest] syntax sugar for lazy instantiation

Ashley Williams ashpublic at mac.com
Tue Jun 23 17:14:47 EDT 2009


Yes this is in effect a single check, not double. Thanks, I wouldn't  
have seen that error for hours.

On 23 Jun 2009, at 22:08, Jim Andreou wrote:

> There is a typo inside the synchronized block, it should be obj ==  
> null.
>
> All in all, it looks good, saves some boilerplate.
>
> 2009/6/24 Ashley Williams <ashpublic at mac.com>
> Included this so now we have:
>
> @ThreadSafe
> public abstract class LazyField<T> implements Callable<T> {
> 	private volatile T obj;
>
> 	public T get() {
> 		// use a local variable to save on multiple reads of a volatile
> 		T result = obj;
> 		if (result == null) {
> 			synchronized (this) {
> 				if (result == null) {
> 					result = call();
> 					obj = result;
> 				}
> 			}
> 		}
> 		return result;
> 	}
> }
>
> with usage example:
>
> 	private final LazyField<Logger> antLogger = new LazyField<Logger>() {
> 		public Logger call() throws Exception {
> 			return Logger.getLogger(Log4jListener.LOG_ANT);
> 		}
> 	};
>
> Looking a lot tidier now.
>
>
> On 23 Jun 2009, at 19:47, Jim Andreou wrote:
>
>> An piece of advice from Josh Bloch:
>>
>> 		if (obj == null) {
>>                     ....
>> 		}
>> 		return obj;
>>
>> It's better to store obj in a local field and use that for these  
>> two reads, this way you save a volatile read operation.
>>
>>
>> I very much like Scala's implementation of this (though this is a  
>> language feature instead of a library): lazy val function = ...,  
>> and there, you got a nice version of the double checked locking  
>> idiom created for you :) (which also allows the lengthy computation  
>> to return just null, since it uses an extra bit to encode whether  
>> the field is initialized or not).
>>
>> Dimitris
>>
>> 2009/6/23 Ashley Williams <ashpublic at mac.com>
>> 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
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>
>

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


More information about the Concurrency-interest mailing list