Java的单例模式

1.Java的单例模式有7中写法,我们来一一介绍一下。

2.懒汉式

public class Singleton1 {
    private Singleton1() {
    }
    private static Singleton1 instance;//懒汉式
    public static Singleton1 getInstance(){//存在线程安全问题,假如两个线程同时判断到instance为空,就会创建两个对象了。
        if (instance == null)
            instance = new Singleton1();
        return instance;
    }
}

它是线程不安全的,所以不建议使用。

3.线程安全的懒汉式

public class Singleton2 {
    private Singleton2() {
    }
    private static Singleton2 instance;//懒汉式
    public static synchronized Singleton2 getInstance(){//不存在线程安全问题,但每次获取对象时,都需要持有锁;在Java中锁是很耗资源和性能的
        if (instance == null)
            instance = new Singleton2();
        return instance;
    }
    public static Singleton2 getInstance1(){//不存在线程安全问题,但每次获取对象时,都需要持有锁;在Java中锁是很耗资源和性能的
        synchronized (Singleton2.class) {
            if (instance == null)
                instance = new Singleton2();
        }
        return instance;
    }
}

就是加锁的方式,但是单例new就执行一次,多数情况都是要去调用getInstance方法;这里加了锁,所以每次获取对象时都要去过去锁,很耗资源和性能,很耗时;也不建议使用。

4.懒汉式,双重检验锁

public class Singleton3 {
    private Singleton3() {
    }
    private static Singleton3 instance;//懒汉式,双重检验锁
    public static Singleton3 getInstance(){//不存在线程安全问题,只有在为空时才加锁,然后再判空;减少了获取锁的消耗
        if (instance == null){
            synchronized (Singleton3.class) {
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}

这种写法是线程安全的,并且不会很耗时;但写法稍微复杂。

5.饿汉式

public class Singleton4 {
    private Singleton4() {
    }
    private static Singleton4 instance = new Singleton4();//饿汉式,如果没有使用到,会浪费内存,因为类一加载就创建对象了
    public static Singleton4 getInstance(){
        return instance;
    }
}

这种写法是线程安全的,但在类加载时就会申请内存;假如开始没有使用的话,一定程度上浪费了内存空间;不太符合程序的懒加载思想。

6.饿汉式

public class Singleton5 {
    private Singleton5() {
    }
    private static Singleton5 instance;//饿汉式,如果没有使用到,会浪费内存,因为类一加载就创建对象了
    static {
        instance = new Singleton5();
    }
    public static Singleton5 getInstance(){
        return instance;
    }
}

它和上面的一样的,只是把静态变量写到了静态代码块中。

7.饿汉式静态内部类

public class Singleton6 {
    private Singleton6() {
    }
    private static class Singleton5Holder{
        private static Singleton6 instance = new Singleton6();
    }
    public static Singleton6 getInstance(){//静态内部类的方式,只有调用此方法了,才会创建对象,节省内存
        return Singleton5Holder.instance;
    }
}

这里使用了静态内部类的方法来返回对象;这样在类加载时,不会创建对象;当使用时,会调用一次静态内部类,创建好对象;符合懒加载思想,也不会造成内存浪费;写法相对与懒汉式也简单;所以建议使用这种方式。

8.枚举类

public enum Singleton7 {
    INSTANCE;
    //查看编译后的class文件,发现自动添加了私有的无参构造方法;和单例是很像的;
    // 也就是说这个类的实例对象INSTANCE是唯一的,这就是单例

    //下面就可以写各种对这个类的方法或业务逻辑处理了;
    public void method(){
    }
}

就是使用一个枚举来表示;但实际工作中很少使用过这种方式,至少我本人是这样的;Effective Java第二版中倒是建议使用这种方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值