java设计模式——单例模式

本文详细介绍了Java中的单例模式实现方式,包括饿汉式、懒汉式、线程安全的懒汉式、双检锁、静态内部类、枚举以及如何防止反射、序列化和克隆破坏单例。此外,还探讨了有限多例模式在线程池场景的应用,并分析了多例模式的安全性和限制。
摘要由CSDN通过智能技术生成

1.eager

/**
 * 单例模式eager
 */
public class Singleton_eager {
    //单例
    private Singleton_eager INSTANCE=new Singleton_eager();

    //构造方法私有化
    private Singleton_eager() {
    }

    //获得实例化
    public Singleton_eager getInstance() {
        return INSTANCE;
    }
}

2.lazy

/**
 * 单例模式lazy
 */
public class Singleton_lazy {
    //单例
    private Singleton_lazy INSTANCE=null;

    //构造方法私有化
    private Singleton_lazy() {
    }

    //获取实例化
    public Singleton_lazy getInstance(){
        if(INSTANCE==null){
            INSTANCE=new Singleton_lazy();
        }
        return INSTANCE;
    }
}

3.lazy线程安全

/**
 * 单例模式lazy
 * 线程安全
 */
public class Singleton_threadSafety {
    private volatile static Singleton_Threadsafety INSTANCE;

    private Singleton_threadSafety() {
    }

    public static synchronized Singleton_threadSafety getInstance() {
        if(INSTANCE!=null){
            INSTANCE=new Singleton_threadSafety();
        }
        return INSTANCE;
    }
}

4.lazy双检锁

/**
 * 单例模式
 * 双检锁(double check lock)
 */
public class Singleton_DCL {
    //单例
    private Singleton_DCL INSTANCE;

    //构造方法实例化
    private Singleton_DCL() {
    }

    //双重检验 第一个if提升效率 第二个if控制实例生成
    public Singleton_DCL getInstance() {
        if(INSTANCE==null){
            synchronized(INSTANCE){
                if(INSTANCE==null){
                    INSTANCE=new Singleton_DCL();
                }
            }
        }
        return INSTANCE;
    }
}

5.静态内部类

/**
 * 单例模式
 * 静态内部类
 */
public class Singleton_staticInner {
    private Singleton_staticInner(){
    }
    //静态内部类
    private static class singletonHolder{
        private static final Singleton_staticInner INSTANCE=new Singleton_staticInner();
    }
    public static Singleton_staticInner getInstance(){
        return singletonHolder.INSTANCE;
    }
}

6.枚举

/**
 * 单例模式枚举
 */
public enum Singleton_enum {
    INSTANCE;
    public Singleton_enum getInstance(){
        return INSTANCE;
    }
}

7.静态枚举类

public class singleton_staticEnum{
    //私有化构造函数
    private singleton_staticEnum(){ }
 
    //静态枚举类
    static enum singleton_staticEnumHolder{
        INSTANCE;
        private singleton_staticEnum INSTANCE;
     
        private singleton_staticEnumHolder(){
            user=new User();
        }
        public User getInstnce(){
            return INSTANCE;
        }
    }
    //实例化
    public static User getInstance(){
        return singleton_staticEnumHolder.INSTANCE.getInstnce();
    }
}

8.防止反射破坏

/**
 * 单例模式eager
 * 防止反射破坏
 */
public class Singleton_safety {
    private Singleton_safety INSTANCE=new Singleton_safety();

    private Singleton_safety() {
        //当进行发射时,会进行判断,如果存在实例则直接报错,如果实例不存在,则发射创建实例
        if(INSTANCE!=null){
            throw new UnsupportedOperationException("实例化已存在,无法初始化");
        }
    }

    public Singleton_safety getInstance() {
        return INSTANCE;
    }
}

9.防止序列化破坏

/**
 * 单例模式eager
 * 防止反射破坏
 */
public class Singleton_safety {
    private Singleton_safety INSTANCE=new Singleton_safety();

    //当进行反序列化时,会自动调用该方法,将该方法的返回值直接返回,防止被破坏
    public Object readResolve(){
        return INSTANCE;
    }
}

10.防止克隆破坏

/**
 * 单例模式eager
 * 防止反射破坏
 */
public class Singleton_safety implements Cloneable{
    private Singleton_safety INSTANCE=new Singleton_safety();

    private Singleton_safety() {
    }

    public Singleton_safety getInstance() {
        return INSTANCE;
    }

    @Override
    protected Object clone(){
        return INSTANCE;
    }
}

结合以上两种

/**
 * 单例模式eager
 * 防止反射和序列化破坏
 */
public class Singleton_safety {
    private Singleton_safety INSTANCE=new Singleton_safety();

    private Singleton_safety() {
        //当进行发射时,会进行判断,如果存在实例则直接报错,如果实例不存在,则发射创建实例
        if(INSTANCE!=null){
            throw new UnsupportedOperationException("实例化已存在,无法初始化");
        }
    }

    public Singleton_safety getInstance() {
        return INSTANCE;
    }

    //当进行反序列化时,会自动调用该方法,将该方法的返回值直接返回,防止被破坏
    public Object readResolve(){
        return INSTANCE;
    }
}

测试单例模式是否被破坏

/**
 * 破坏单例模式
 * 序列化和反射
 */
public class Singleton_destroy {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //序列化测试——破坏单例模式
        String file="D:/destroySingleton.txt";
        Sington singleton = new Sington();
        writeObject2File(file,singleton);
        //比较读取两次地址是否相同,不同则单例模式被破坏
        readObject4File(file);
        readObject4File(file);

        //发射测试——破坏单例模式
        //获取singleton字节码对象
        Class<Sington> aClass = Sington.class;
        //获取无参构造方法
        Constructor<Sington> cons = aClass.getDeclaredConstructor();
        //取消访问权限检查
        cons.setAccessible(true);
        //实例化两次
        Sington s1 = cons.newInstance();
        Sington s2 = cons.newInstance();
        System.out.println(s1==s2);//如果返回true则单例模式没有被破坏,返回false则单例模式被破坏
    }

    //从文件中读取数据
    public static void readObject4File(String file) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        Sington instance = (Sington) ois.readObject();
        System.out.println(instance);
        ois.close();
    }

    //写数据到文件
    public static void writeObject2File(String file,Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(obj);
        oos.close();
    }
}

11.有限多例模式

/**
 * 有限多例模式(multiton)
 */
public class Singleton_multiton {
    private static ArrayList<Singleton_multiton> INSTANCES;
    private static final int count=5;

    private Singleton_multiton() {
    }

    static {
        for (int i = 0; i < 5; i++) {
            INSTANCES.add(new Singleton_multiton());
        }
    }

    public static Singleton_multiton getInstance(){
        int r= (int) (Math.random()*count);
        return INSTANCES.get(r);
    }
}

/**
 * 有限多例模式
 * 用于线程池
 * 没有控制池大小
 */
public class Singleton_Thread {
    private static HashMap<Integer, Singleton_Thread> pool=new HashMap<>();

    private Singleton_Thread() {
    }

    public static Singleton_Thread getInstance(int key){
        Singleton_Thread thread = pool.get(key);
        if(thread==null){
            thread=new Singleton_Thread();
            pool.put(key,thread);
        }
        return thread;
    }
}


/**
 * 有限多例模式
 * 用于线程池
 * 控制池大小
 */
public class Singleton_Thread1 {
    private static HashMap<Integer, Singleton_Thread1> pool=new HashMap<>();
    private static int MAX_SIZE=3;
    private static int num=0;

    private Singleton_Thread1() {
    }

    public static Singleton_Thread1 getInstance(){
        Singleton_Thread1 thread = pool.get(num);
        if(thread==null){
            thread=new Singleton_Thread1();
            pool.put(num,thread);
        }
        num=(num+1)%MAX_SIZE;
        return thread;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值