资讯专栏INFORMATION COLUMN

Java 23种设计模式 之单例模式 7种实现方式

IntMain / 2193人阅读

摘要:一懒汉式线程不安全懒汉式线程不安全私有构造方法只允许在内部进行实例的创建创建实例二懒汉式线程安全懒汉式线程安全私有构造方法只允许在内部进行实例的创建创建实例线程安全三饿汉式线程安全饿汉式私有构造方法只允许在内部进行实例的创建静态初始化由保证

一、懒汉式(线程不安全)

package com.java.singleton;

//懒汉式 线程不安全
public class LazySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private LazySingleton() {
    }


    private static LazySingleton instance = null;

    //创建实例
    public static LazySingleton getInstance() {

        if (instance == null) {
            instance = new LazySingleton();
        }

        return instance;
    }
}

二、懒汉式(线程安全)

package com.java.singleton;

//懒汉式 线程安全
public class SynchronizedLazySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private SynchronizedLazySingleton() {
    }


    private static SynchronizedLazySingleton instance = null;

    //创建实例  线程安全
    public static synchronized SynchronizedLazySingleton getInstance() {

        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }

        return instance;
    }

}

三、饿汉式(线程安全)

package com.java.singleton;

//饿汉式
public class HungrySingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private HungrySingleton() {
    }

    //静态初始化 由JVM保证线程安全
    private static HungrySingleton instance = new HungrySingleton();

    //创建实例
    public static HungrySingleton getInstance() {

        return instance;
    }

}

四、缓存实现(线程不安全)

package com.java.singleton;

import java.util.HashMap;
import java.util.Map;

//线程不安全 缓存实现
public class CacheSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private CacheSingleton() {
    }

    //构造缓存容器
    private static Map map = new HashMap<>();

    //构造默认的存放key
    private static final String DEFAULT_KEY = "Cache";


    //创建实例
    public static CacheSingleton getInstance() {

        //先从缓存中取 没有就创建并放入缓存  有就返回
        CacheSingleton instance = (CacheSingleton) map.get(DEFAULT_KEY);

        if (instance == null) {

            instance = new CacheSingleton();
            map.put(DEFAULT_KEY, instance);
        }

        return instance;
    }

}

五、双重检查加锁(懒汉式 线程安全的进一步优化)

package com.java.singleton;


//双重检查加锁  懒汉式在方法上加synchronized的进一步优化
public class DoubleCheckedLockingSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private DoubleCheckedLockingSingleton() {
    }

    //volatile 修饰的变量不会被本地线程缓存 对该变量的读写直接作用于共享内存 类似于互斥锁
    private volatile static DoubleCheckedLockingSingleton instance = null;

    //创建实例
    public static DoubleCheckedLockingSingleton getInstance() {

        if (instance == null) {

            synchronized (DoubleCheckedLockingSingleton.class) {

                if (instance == null) {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }

        }

        return instance;
    }


}

六、 Lazy Initialization Holder Class实现单例

package com.java.singleton;


//静态内部类 Lazy Initialization Holder Class
public class LazyInitializationHolderClassSingleton {

    //私有构造方法 只允许在内部进行实例的创建
    private LazyInitializationHolderClassSingleton() {
    }

    /*
     * 静态成员式内部类 该内部类的实例对象与外部类的实例无绑定关系
     * 有且只有在LazyInitializationHolder被调用instance时 在会对对象实例进行装载
     * 从而实现延时加载
     */
    private static class LazyInitializationHolder {

        /*
         * 静态初始化器 由JVM保证线程安全
         *
         */
        private static LazyInitializationHolderClassSingleton instance = new LazyInitializationHolderClassSingleton();
    }


    //创建实例
    public static LazyInitializationHolderClassSingleton getInstance() {

        return LazyInitializationHolder.instance;
    }


}

七、枚举实现单例

package com.java.singleton;

public enum EnumSingleton {

    //枚举类的每个元素 都代表一个单例
    uniqueEnumSingleton;


    public  void method() {

        System.out.println("EnumSingleton"+uniqueEnumSingleton.hashCode());
    }

}

八、测试类

package com.java.singleton;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SingletonApplicationTests {

    @Test
    public void testCacheSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("CacheSingleton	" + CacheSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }

    @Test
    public void testDoubleCheckedLockingSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("DoubleCheckedLockingSingleton	" + DoubleCheckedLockingSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }

    @Test
    public void testEnumSingleton() {

        for (int i = 0; i < 3; i++) {

            EnumSingleton.uniqueEnumSingleton.method();
        }
        System.out.println("-------------------------------------------------------------------
");
    }


    @Test
    public void testHungrySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("HungrySingleton	" + HungrySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }


    @Test
    public void testLazyInitializationHolderClassSingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazyInitializationHolderClassSingleton	" + LazyInitializationHolderClassSingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }

    @Test
    public void testLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("LazySingleton	" + LazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }


    @Test
    public void testSynchronizedLazySingleton() {

        for (int i = 0; i < 3; i++) {

            System.out.println("SynchronizedLazySingleton	" + SynchronizedLazySingleton.getInstance());
        }
        System.out.println("-------------------------------------------------------------------
");
    }


}

九、测试结果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73204.html

相关文章

  • 设计模式单例模式

    摘要:反射攻击首先我们来看一下反射调用,以双重检验方式为例反射攻击输出结果是反射攻击结果私有构造方法被调用次私有构造方法被调用次从结果可以看到,私有的构造函数被调用了两次,也就是说这样的单例模式并不安全。 showImg(https://segmentfault.com/img/bV1fer?w=900&h=500); 保证一个类仅有一个实例,并提供一个访问它的全局访问点。——艾迪生维斯理 ...

    cnsworder 评论0 收藏0
  • 优才公开课笔记:php设计模式(一) 单例模式

    摘要:最近开展了三次设计模式的公开课,现在来总结一下设计模式在中的应用,这是第一篇创建型模式之单例模式。不过因为不支持多线程所以不需要考虑这个问题了。 最近开展了三次设计模式的公开课,现在来总结一下设计模式在PHP中的应用,这是第一篇创建型模式之单例模式。 一、设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用、容易被他人理解的、可靠的代码设计经验的总结。 设计模式不...

    guyan0319 评论0 收藏0
  • 设计模式单例模式

    摘要:单例模式关注的重点私有构造器线程安全延迟加载序列化和反序列化安全反射攻击安全相关设计模式单例模式和工厂模式工厂类可以设计成单例模式。 0x01.定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点 类型:创建型 UML showImg(https://segmentfault.com/img/bVbtDJ2?w=402&h=268); 单例模式的基本要素 私有的构造方...

    陆斌 评论0 收藏0
  • Java基础学习——多线程单例设计模式(转)

    摘要:总之,选择单例模式就是为了避免不一致状态,避免政出多头。二饿汉式单例饿汉式单例类在类初始化时,已经自行实例化静态工厂方法饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。 概念:  Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例、饿汉式单例。  单例模式有以下特点:  1、单例类只能有一个实例。 ...

    dendoink 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<