java中延迟线程安全单例实例化的模式 [英] Pattern for lazy thread-safe singleton instantiation in java

查看:201
本文介绍了java中延迟线程安全单例实例化的模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

懒惰的线程安全单例实例对每个编码器都不容易理解,所以我想在我们的企业框架中创建一个可以完成这项工作的类。



<你怎么看?你觉得它有什么坏处吗?在Apache Commons中有类似的东西吗?我怎样才能做得更好?



Supplier.java

  public界面供应商< T> {
public T get();
}

LazyThreadSafeInstantiator.java

  public class LazyThreadSafeInstantiator< T>实施供应商< T> {
私人最终供应商< T> instanceSupplier;

private volatile T obj;

public LazyThreadSafeInstantiator(Supplier< T> instanceSupplier){
this.instanceSupplier = instanceSupplier;
}

@Override
// http://en.wikipedia.org/wiki/Double-checked_locking
public T get(){
T result = obj; //维基百科:注意局部变量结果的使用似乎是不必要的。对于Java VM的某些版本,它将使代码速度提高25%,而对于其他版本,它不会受到影响。
if(result == null){
synchronized(this){
result = obj;
if(result == null){
result = instanceSupplier.get();
obj =结果;
}
}
}
返回结果;
}
}

用法示例:

 公共类Singleton1 {
private static final Supplier< Singleton1> instanceHolder =
new LazyThreadSafeInstantiator< Singleton1>(new Supplier< Singleton1>(){
@Override
public Singleton1 get(){
return new Singleton1();
}
});

public Singleton1 instance(){
return instanceHolder.get();
}

private Singleton1(){
System.out.println(Singleton1 instantiated);
}
}

谢谢

解决方案


懒惰的线程安全单例
instantion对每个编码器来说都不容易
了解


不,它实际上非常非常简单:

  public class Singleton {
private final static Singleton instance = new Singleton();
private Singleton(){...}
public static Singleton getInstance(){return instance; }
}

更好的是,让它成为枚举:

  public enum Singleton {
INSTANCE;
private Singleton(){...}
}

这是线程安全的,并且它是懒惰的(初始化发生在类加载时,并且Java在第一次引用它们之前不加载类。)



事实是,99%的时间你根本不需要延迟加载。在剩下的1%中,在0.9%中,上述内容非常懒惰。



您是否运行过分析器并确定您的应用程序属于0.01%需要延迟加载首次访问?不这么认为。那你为什么要浪费时间来编造这些Rube Goldbergesque代码的可憎之处来解决一个不存在的问题呢?


the lazy thread-safe singleton instantion is kinda not easy to understand to every coder, so i wanted to create a class in our enterprise framework that would do the job.

What do you think about it? Do you see something bad about it? Is there something similar like in Apache Commons? How can i make it better?

Supplier.java

public interface Supplier<T> {
    public T get();
}

LazyThreadSafeInstantiator.java

public class LazyThreadSafeInstantiator<T> implements Supplier<T> {
    private final Supplier<T> instanceSupplier;

    private volatile T obj;

    public LazyThreadSafeInstantiator(Supplier<T> instanceSupplier) {
        this.instanceSupplier = instanceSupplier;
    }

    @Override
    // http://en.wikipedia.org/wiki/Double-checked_locking
    public T get() {
        T result = obj;  // Wikipedia: Note the usage of the local variable result which seems unnecessary. For some versions of the Java VM, it will make the code 25% faster and for others, it won't hurt.
        if (result == null) {
            synchronized(this) {
                result = obj;
                if (result == null) {
                    result = instanceSupplier.get();
                    obj = result;
                }
            }
        }
        return result;
    }
}

Example usage:

public class Singleton1 {
    private static final Supplier<Singleton1> instanceHolder =
        new LazyThreadSafeInstantiator<Singleton1>(new Supplier<Singleton1>() {
            @Override
            public Singleton1 get() {
                return new Singleton1();
            }
        });

    public Singleton1 instance() {
        return instanceHolder.get();
    }

    private Singleton1() {
        System.out.println("Singleton1 instantiated");
    }
}

Thanks

解决方案

the lazy thread-safe singleton instantion is kinda not easy to understand to every coder

No, it's actually very, very easy:

public class Singleton{
    private final static Singleton instance = new Singleton();
    private Singleton(){ ... }
    public static Singleton getInstance(){ return instance; }
}

Better yet, make it an enum:

public enum Singleton{
    INSTANCE;
    private Singleton(){ ... }
}

It's threadsafe, and it's lazy (initialization happens at class loading time, and Java does not load classes until they are are first referred).

Fact is, 99% of the time you don't need lazy loading at all. And out of the remaining 1%, in 0.9% the above is perfectly lazy enough.

Have you run a profiler and determined that your app belings to the 0.01% that really needs lazy-loading-at-first-access? Didn't think so. Then why are you wasting your time concocting these Rube Goldbergesque code abominations to solve a non-existing problem?

这篇关于java中延迟线程安全单例实例化的模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆