设计模式——单例模式

定义:单例模式就是一个类只能有一个实例。
实现单例模式的必要条件:
1、类构造器必须是私有的
2、一个静态的该类对象
3、一个获取实例对象的静态方法

单例模式的使用场景:在一个系统中要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式。

单例模式优缺点:
优点:内存开支少;减少了系统的性能开销;避免对资源的多重占用;可以在系统设置全局的访问点,避免对同一个资源文件进行写操作。
缺点:单例模式一般没有接口,所以扩展困难。

饿汉式

这种方式是,不管你会不会用到该类的实例,系统都会帮你创建好。
优点:线程安全,不用加锁,提高效率
缺点:类加载时就进行初始化,浪费内存

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {

    }

    public static Singleton getSingleton() {
        return singleton;
    }
}

懒汉式

这个方式会把实例对象的创建延迟到真正使用的时候。

线程不安全的方式

public class Singleton02 {
    private static Singleton02 singleton;

    private Singleton02() {

    }

    public static Singleton02 getSingleton() {
        if (singleton == null) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton=new Singleton02();
        }
        return singleton;
    }
}

通过以下代码可以验证线程不安全 :

    @Test
    public void dmeo1() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Callable<Singleton02> callable=new Callable<Singleton02>() {
            @Override
            public Singleton02 call() throws Exception {
                return Singleton02.getSingleton();
            }
        };
        Future<Singleton02> s1 = executorService.submit(callable);
        Future<Singleton02> s2 = executorService.submit(callable);
        System.out.println(s1.get()==s2.get());

    }

线程安全的方式

双重校验锁

public class Singleton03 {
    private static Singleton03 singleton;

    private Singleton03() {

    }

    public static Singleton03 getSingleton() {
        if (singleton == null) {
            synchronized (Singleton03.class) {
                if (singleton == null) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    singleton=new Singleton03();
                }
            }
        }
        return singleton;
    }
}

上面的代码使用双重检查机制,可以优化执行效率。使得之后调用该方法时,不需要在singleton不为null时,还去获取锁,之后再去同步代码块中检查,singleton是否为null。

内部类

public class Singleton04 {
    private Singleton04() {

    }

    public static Singleton04 getSingleton() {
        return InnerClass.singleton;
    }

    private static class InnerClass{
        private static Singleton04 singleton=new Singleton04();
    }

}

使用内部类实现单例模式就写起来很简单,效率也高。
内部类的加载时期是它第一次被使用的时候,而且类只能被加载一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值