hbase-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ryan Rawson <ryano...@gmail.com>
Subject Re: Review Request: HBASE-2578
Date Wed, 26 May 2010 06:26:28 GMT
Sounds like we want #1: replaceable singleton.

does that sound right?

On Tue, May 25, 2010 at 9:16 PM, Paul Cowan <cowan@aconex.com> wrote:
> On 26/05/2010 1:54 PM, Ryan Rawson wrote:
>>
>> Thanks for that salient comment. Perhaps someone can give us the right
>> pattern for no lock Singleton initialization.
>
> There are really only two things which complicate thread-safe singletons:
>
> 1) Having a setter, so you can replace the singleton
> 2) Lazy initialization. The only excuse for this is having a
> horribly-expensive-to-create singleton, which may not even be used, and you
> don't under any circumstances wish to create it unless it's needed. This is
> hard to get right, and 99% of the time you should just instantiate it at
> class initializion time and forget it.
>
> In this case, 1) applies, but 2) doesn't; luckily 1) is a lot easier to get
> right than 2).
>
> Simplest 'correct' patterns are:
>
>
> Basic Singleton (neither #1 nor #2 apply)
> -------------------------------------------
>
> public class Thing {
>   private static final Thing INSTANCE = new AwesomeThing();
>
>   public Thing get() {
>      return INSTANCE;
>   }
> }
>
> this is easy, simple, performant (no synchronization or locking at all) and
> 100% thread-safe (as long as INSTANCE is final).
>
>
>
> Replacable Singleton (#1 applies)
> -------------------------------------------
> public class Thing {
>   private static volatile Thing instance = new AwesomeThing(); // Note:
> volatile
>
>   public Thing get() {
>      return instance;
>   }
>
>   public void set(Thing newThing) {
>      this.instance = newThing;
>   }
> }
>
> Nearly as easy, all that's required here is a volatile instance which gives
> you the correct happens-before relationship.
>
>
>
> Lazy-Initialized Singleton (#2 applies)
> -------------------------------------------
> Avoid if possible, but if not, one of:
>
> Synchronized Getter:
>   public synchronized Thing get() {
>      if (instance == null) {
>          instance = new AwesomeThing();
>      }
>      return instance;
>   }
>
> Double-checked locking (ONLY works in Java 5+)
>   public Thing get() {
>      if (instance == null) {
>          synchronized (ThingHolder.class) {
>             if (instance == null) { // Yes, you need this
>                 instance = new AwesomeThing();
>             }
>         }
>      }
>      return instance;
>
> Use java classloading locking guarantees + holder class (see: Effective
> Java)
>   class ThingHolder {
>       private static final Thing INSTANCE = new AwesomeThing();
>   }
>
>   class Thing {
>       public Thing getThing() {
>           return ThingHolder.instance;
>       }
>   }
>
>
>
> Lazy-Initialized Settable Singleton (#1 + #2 apply)
> -------------------------------------------
> You almost certainly don't need this. You think you do, but you don't. Find
> a better way. :)
>
>
> Hope that helps.
>
> Cheers,
>
> Paul
>

Mime
View raw message