Java 实现单例

来源:互联网 发布:横截面数据举例 编辑:程序博客网 时间:2024/05/29 07:09

懒汉(线程不安全)

public class Singleton {    private static Singleton instance = null;    private Singleton () {    }    public static Singleton getInstance () {        if (instance == null) {            instance = new Singleton();        }        return instance;    }}

懒汉(线程安全)

public class Singleton {    private static Singleton instance = null;    private Singleton () {    }    synchronized public static Singleton getInstance () {        if (instance == null) {            instance = new Singleton();        }        return instance;    }}

饿汉(线程安全)

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

饿汉变种(线程安全)

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

懒汉(静态内部类)

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

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟第三种和第四种方式不同的是(很细微的差别):
第三种和第四种方式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。
因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。
想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比第三和第四种方式就显得很合理。

枚举

public enum Singleton {    INSTANCE;    public void whatevermethod() {    }}

Effective Java作者Josh Bloch 提倡的方式,不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少看见有人这么写过。

饿汉(线程安全、双重校验锁)

public class Singleton {    private Singleton () {    }    private volatile static Singleton instance = null;    public static Singleton getInstance() {        if (instance == null) {            synchronized (Singleton.class) {                if (instance == null) {                    instance = new Singleton();                }            }        }        return instance;    }}

Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类。内部类又分为:常规内部类、局部内部类、匿名内部类和静态嵌套类四种。
1、静态内部类定义
静态内部类,定义在类中,任何方法外,用static定义;静态内部类只能访问外部类的静态成员。
生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。可以定义私有静态内部类。
2、java实现静态内部类注意事项
将某个内部类定义为静态类,跟将其他类定义为静态类的方法基本相同,引用规则也基本一致。不过其细节方面仍然有很大的不同。具体来说,主要有如下几个地方要引起注意。
1)一般情况下,如果一个内部类不是被定义成静态内部类,那么在定义成员变量或者成员方法的时候,是不能够被定义成静态成员变量与静态成员方法的。也就是说,在非静态内部类中不可以声明静态成员
2)一般非静态外部类可以随意访问其外部类的成员变量以及方法(包括声明为private的方法),但是如果一个内部类被声明为static,则其在访问包括自身的外部类会有诸多的限制。静态内部类不能访问其外部类的非静态成员变量和方法
3)在一个类中创建非静态成员内部类的时候,有一个强制性的规定,即内部类的实例一定要绑定在外部类的实例中。然后要在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例。即在创建静态类内部对象时,不需要其外部类的对象

0 0
原创粉丝点击