zoukankan      html  css  js  c++  java
  • 设计模式之单例(singleton)设计模式代码详解

    单例有两种:懒汉式和饿汉式

    /**
     * 懒汉式的单例模式
     * 这种单例模式如果采用到多线程调用该方法,有可能会产生多个实例,原因是:
     * 当线程一进入了①处,此时轮到线程二的时间片,线程二也来到①处,则两个线程各自会创建实例,这样就不满足单例模式的目标了
     * 解决办法有三种:
     * 1.将懒汉式转换成饿汉式,当类加载的时候就完成对该实例的创建,这样多线程操作的时候只会获取该实例而不会创建该实例,自然也不会产生多个实例了
     * 2.在getInstance方法前加入synchronized关键字
     * 3.“双重检查加锁”
     * User: HYY
     * Date: 13-11-15
     * Time: 下午12:28
     * To change this template use File | Settings | File Templates.
     */
    public class LazySingleton {
        private static LazySingleton mySingleton;
    
        private LazySingleton(){}
    
        public static LazySingleton getInstance() {
            if(mySingleton==null) {
                //
                mySingleton = new LazySingleton();
            }
            return mySingleton;
        }
    
        public void businessMethod() {
            System.out.println("业务方法");
        }
    
        public static void main(String[] args) {
            LazySingleton singleton = LazySingleton.getInstance();
            singleton.businessMethod();
            LazySingleton singleton2 = LazySingleton.getInstance();
            System.out.println("1==2:"+(singleton==singleton2));
        }
    }

    这种单例模式如果采用到多线程调用该方法,有可能会产生多个实例,原因是:
    当线程一进入了①处,此时轮到线程二的时间片,线程二也来到①处,则两个线程各自会创建实例,这样就不满足单例模式的目标了
    解决办法有三种:
    * 1.将懒汉式转换成饿汉式,当类加载的时候就完成对该实例的创建,这样多线程操作的时候只会获取该实例而不会创建该实例,自然也不会产生多个实例了
    * 2.在getInstance方法前加入synchronized关键字
    * 3.“双重检查加锁”

    /**
     * 饿汉式单例模式
     * 这种单例模式能够解决多线程创建多个实例对象的问题
     * 采用了这种方式再也不用担心多线程对该对象的多次实例
     * 当类被加载的时候就已经初始化该实例,如果该类是一个庞大的实例,常驻一大块内存,则这样不是一个好设计。应当在需要的时候再去实例该对象(懒汉式)
     * User: HYY
     * Date: 13-11-15
     * Time: 下午12:38
     * To change this template use File | Settings | File Templates.
     */
    public class HungrySingleton {
        private static HungrySingleton hungrySingleton = new HungrySingleton();
    
        private HungrySingleton(){}
    
        public HungrySingleton getInstance() {
            return hungrySingleton;
        }
    }
    /**
     * 在getInstance方法前面添加synchronized关键字解决多线程的问题。
     *
     * 如果有很多线程要获取这个单例,则这种设计方式比较低效。为什么?
     * 要知道synchronized关键字有可能使程序的效率降低100倍。
     * User: HYY
     * Date: 13-11-15
     * Time: 下午12:34
     * To change this template use File | Settings | File Templates.
     */
    public class SyncSingleton {
        private static SyncSingleton syncSingleton;
    
        private SyncSingleton(){}
    
        public synchronized static SyncSingleton getInstance() {
            if(syncSingleton==null) {
                syncSingleton = new SyncSingleton();
            }
            return syncSingleton;
        }
    }
    /**
     * 我们其实只需要保证在创建的时候有只有一个线程负责该单例的创建即可。
     * 因此我们采用“双重检查加锁”方式(即只加锁创建实例部分的代码)
     *
     * User: HYY
     * Date: 13-11-15
     * Time: 下午12:56
     * To change this template use File | Settings | File Templates.
     */
    public class DoubleCheckSingleton {
        private volatile static DoubleCheckSingleton syncSingleton;
    
        private DoubleCheckSingleton(){}
    
        public static DoubleCheckSingleton getInstance() {
            if(syncSingleton==null) {//如果还没有进行实例化
                //
                synchronized (DoubleCheckSingleton.class) {//准备进入创建操作,在此之前先判断创建操作是否已经加锁
                    if(syncSingleton==null) {//再次判断是否已经加锁,如果没有这句判断,那么已经进入①处的线程还会进行实例化
                        syncSingleton = new DoubleCheckSingleton();
                    }
                }
            }
            return syncSingleton;
        }
    }
  • 相关阅读:
    【网页前端】JS呈现时间戳为与当前时间比较结果
    【Django工具】Django_debug_toolbar使用
    【Django Models】Django数据查询 汇聚
    【Django Models】虚拟化提取Models公共的功能
    【网页在线编辑】图文发送的模式
    【Django后台数据管理】后台数据新建或者保存,经常遇到提示This field is required
    【BBS】Discuz部署
    【Django】QuerySet的分页和排序
    【Django数据库】如何将一个表自定义的key列还原成id列作为key
    18.6
  • 原文地址:https://www.cnblogs.com/wuyou/p/3425139.html
Copyright © 2011-2022 走看看