最全的单例模式

普通创建对象

/**
 * @author jason jason@aistrong.com
 * @date 2021/1/21 18:20
 */
/**
 * @author jason jason@aistrong.com
 * @date 2021/1/21 18:20
 */
public class Person {

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

输出结果

发现每次创建对象都是新的对象,单例模式要求每次创建的对象是同一个对象
com.aistrong.singleton.Person@74b47802
com.aistrong.singleton.Person@74f84cf
com.aistrong.singleton.Person@72d6db17
com.aistrong.singleton.Person@5015b31e

饿汉式

/**
 * 饿汉式
 * 优点:写法简单,线程安全
 * 缺点:当类被加载到内存中的时候,就会创建对象,造成内存浪费
 *
 * @author jason jason@aistrong.com
 * @date 2020/12/29 0:41
 */
public class Singleton1 {
    //私有化构造器
    private Singleton1() {
    }

    //当类被加载的时候就会初始化对象
    private static Singleton1 singleton1 = new Singleton1();

    //对外提供访问的方法
    public static Singleton1 getSingleton1() {
        return singleton1;
    }

    //开启100个线程来获取单例对象,看是否每次获取的是同一个对象
    //如果对象的hashCode一致,则证明为同一个对象
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                Singleton singleton = Singleton.getSingleton();
                System.out.println(singleton);
            }).start();
        }
    }
}

懒汉式

/**
 * 懒汉式
 * 优点:不会在类加载到内存中时候就创建对象,相对于饿汉式来说,不会造成内存浪费
 * 缺点:因为是第一次使用的时候去创建对象,在多线程环境中容易造成线程不安全问题
 * @author jason jason@aistrong.com
 * @since 2020/12/29 9:21
 */
public class Singleton {
    //1.私有化构造器
    private Singleton() {
    }

    //定义这个单例对象
    private static volatile Singleton singleton;


    //对外提供方法
    //双重检查锁
    public static Singleton getSingleton() {
        if (singleton == null) {
            //对当前类对象加锁。此处如果用lock也能实现
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

    //开启100个线程来获取单例对象,看是否每次获取的是同一个对象
    //如果对象的hashCode一致,则证明为同一个对象
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                Singleton singleton = Singleton.getSingleton();
                System.out.println(singleton);
            }).start();
        }
    }
}

静态内部类式

/**
 * 匿名内部类方式
 * 优点:即实现了懒加载,又能在不加锁的同时保证线程安全
 * 缺点:代码写法比较少见,不能算缺点
 * 原理:加载一个类时,其内部类不会同时被加载,一个类被加载时,
 * 当且仅当某个静态成员(静态域、构造器、静态方法)被调用时发生
 *
 * @author jason jason@aistrong.com
 * @date 2021/1/21 18:42
 */
public class Singleton2 {


    //私有化构造器
    private Singleton2() {

    }

    //静态内部类被调用的时候,创建外部类的实例对象
    private static class SonSingleton2 {
        private static final Singleton2 instance = new Singleton2();
    }

    //对外提供静态方法提供实例
    public static Singleton2 getInstance() {
        return SonSingleton2.instance;
    }

    //开启100个线程来获取单例对象,看是否每次获取的是同一个对象
    //如果对象的hashCode一致,则证明为同一个对象
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                Singleton2 singleton = Singleton2.getInstance();
                System.out.println(singleton);
            }).start();
        }
    }
}

枚举类式

/**
 * 枚举类实现单例模式
 * 优点:能防止反序列化来创建对象,线程安全
 * 缺点:无
 *
 * @author jason jason@aistrong.com
 * @date 2021/1/21 20:27
 */
public enum DataSourceEnum {

    DATASOURCE;

    private DBConnection connection = null;

    //私有化构造器
    private DataSourceEnum() {
        //内部完成对象创建
        connection = new DBConnection();
    }

    //对外提供实例方法
    public DBConnection getConnection() {
        return connection;
    }

    //测试方法
    //输出结果发现均为同一个对象
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                DBConnection connection = DataSourceEnum.DATASOURCE.getConnection();
                System.out.println(connection);
            }).start();
        }
    }
}
/**
 *  上个类中的 DBConnection 
 * @author jason jason@aistrong.com
 * @date 2021/1/21 20:29
 */
public class DBConnection {

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值