java设计模式--单例

什么是单例

确保一个系统中只有一个实例

使用场景(为什么使用单例)

有些对象需要频繁new,减少开销

N种写法

私有化构造方法,防止其他地方new,提供获取对象的方法;懒汉式:第一次用到才去创建对象;饿汉式:默认创建对象

1. 简单懒汉式(线程不安全)

/**
 * @description 懒汉式,线程不安全
 * @date 2020/12/5 10:45
 */
public class SimpleLazySingleton {
    //懒汉式
    private static SimpleLazySingleton instance;
    //私有
    private SimpleLazySingleton() {

    }
    //获取对象的方法
    public static SimpleLazySingleton getInstance() {

        if(instance == null) {
            //测试线程不安全,先sleep 1
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new SimpleLazySingleton();
        }
        return instance;
    }


    public static void main(String[] args) {
        for(int i = 0; i < 100; i ++) {
            new Thread(()->{
                System.out.println(SimpleLazySingleton.getInstance().hashCode());
            }).start();
        }
    }

}

2. 简单懒汉式(线程安全)
加锁

/**
 * @description 懒汉式,线程安全,线程堵塞
 * @date 2020/12/5 11:24
 */
public class SimpleLazySafeSingleton {
    //懒汉式
    private static SimpleLazySafeSingleton instance;
    //私有
    private SimpleLazySafeSingleton() {

    }
    //获取对象的方法 加锁
    public static synchronized SimpleLazySafeSingleton getInstance() {

        if(instance == null) {
            //测试线程安不安全,先sleep 1
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new SimpleLazySafeSingleton();
        }
        return instance;
    }


    public static void main(String[] args) {
        for(int i = 0; i < 100; i ++) {
            new Thread(()->{
                System.out.println(SimpleLazySafeSingleton.getInstance().hashCode());
            }).start();
        }
    }
}

3. 基于第二种优化懒汉式(线程安全)
需要使用volatile的原因

/**
 * @description 懒汉式相对优化的单例
 * @date 2020/12/5 11:28
 */
public class LazySafeSingleton {
    //懒汉式 
    private static volatile LazySafeSingleton instance;
    //私有
    private LazySafeSingleton() {

    }
    //获取对象的方法
    public static LazySafeSingleton getInstance() {
        //先判断,减少锁
        if(instance == null) {
            //测试线程安不安全,先sleep 1
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //减少加锁的范围 加锁
            synchronized(LazySafeSingleton.class) {
                if(instance == null) {
                    instance = new LazySafeSingleton();
                }
            }
        }
        return instance;
    }


    public static void main(String[] args) {
        for(int i = 0; i < 100; i ++) {
            new Thread(()->{
                System.out.println(LazySafeSingleton.getInstance().hashCode());
            }).start();
        }
    }
}

4. 简单饿汉式单例,线程安全,默认创建了对象

package jiea;

/**
 * @description 简单饿汉式单例,线程安全,即使没使用也会创建对象
 * @date 2020/12/5 11:33
 */
public class SimpleHungrySingleton {
    //创建对象
    private static SimpleHungrySingleton instance = new SimpleHungrySingleton();
    //私有化构造方法
    private SimpleHungrySingleton() {

    }
    //获取对象的方法
    public static SimpleHungrySingleton getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        for(int i = 0; i < 100; i ++) {
            new Thread(()->{
                System.out.println(SimpleHungrySingleton.getInstance().hashCode());
            }).start();
        }
    }
}

5. 基于第4种优化,线程安全由jvm保证

/**
 * @author wuwj
 * @description 内部类静态变量单例
 * @date 2020/12/5 11:42
 */
public class InnerClassLazySafeSingleton {

    //私有化
    private InnerClassLazySafeSingleton() {

    }

    private static class InnerClass{
        private static InnerClassLazySafeSingleton instance = new InnerClassLazySafeSingleton();
    }

    //获取对象的方法
    public static InnerClassLazySafeSingleton getINstance(){
        return InnerClass.instance;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(InnerClassLazySafeSingleton.getINstance().hashCode());
            }).start();

        }
    }
}

6. 枚举实现单例,线程安全,还可以避免反射

package jiea;

/**
 * @description 基于枚举实现的单例
 * @date 2020/12/5 11:58
 */
public enum  EnumSingleton {
    INSTANCE;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                System.out.println(EnumSingleton.INSTANCE.hashCode());
            }).start();
        }
    }
}

==========================end==================
菜鸟也想飞的更高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值