zoukankan      html  css  js  c++  java
  • 单例模式 饿汉与懒汉

    单例模式

    就像任务管理器一样,只能由一个实例,你不能同时打开两个任务管理器,所以单例模式的对象不可以再外部通过new来创建,只能再类里通过private static来保证她的单例属性,再声明一个public函数来访问她。

    ** 私有静态成员单例**+
    私有单例构造函数+
    公有访问函数

    任务管理器例子

    //由于每次使用new关键字来实例化TaskManager类时都将产生一个新对象, 为了确保
    //TaskManager实例的唯一性, 我们需要禁止类的外部直接使用new来创建对象, 因此需要将
    //TaskManager的构造函数的可见性改为private
    
    //构造函数改为private修饰后该如何创建对象呢? 不要着急, 虽然类的外部无法再使用new
    //来创建对象, 但是在TaskManager的内部还是可以创建的, 可见性只对类外有效。 因此, 我们
    //可以在TaskManager中创建并保存这个唯一实例。 为了让外界可以访问这个唯一实例, 需要在
    //TaskManager中定义一个静态的TaskManager类型的私有成员变量,
    
    //为了保证成员变量的封装性, 我们将TaskManager类型的tm对象的可见性设置为private, 但
    //外界该如何使用该成员变量并何时实例化该成员变量呢? 答案是增加一个公有的静态方法,
    
    class TaskManager{
        private static TaskManager tm = null;
        private TaskManager(){}
        public static TaskManager getInstance(){
            if (tm==null){
                tm = new TaskManager();
            }
            return tm;
        }
        public void displayProcess(){}
    
    }
    
    

    负载均衡器

    不管客户端代码。调用几次访问函数,她返回的都是唯一实例(地址相同)

    import java.util.*;
    class LoadBalancer {
        private static LoadBalancer instance = null;
    
        private List serverList = null;
        //私有构造函数
        private LoadBalancer(){
            serverList =new ArrayList();
        }
        //公有静态成员方法。返回唯一实例
        public static LoadBalancer getLoadBalancer(){
            if(instance==null){
                instance =new LoadBalancer();
            }
            return instance;
        }
    
        //add server
        public void addServer(String server){
            serverList.add(server);
        }
    
        //delete server
        public void removeServer(String server){
            serverList.remove(server);
        }
    
        //using Random class randomly gets server
        public String getServer(){
            Random random = new Random();
            int i = random.nextInt(serverList.size());
            return (String)serverList.get(i);
        }
    
    }
    
    

    存在的缺陷

    如果把上列的单例模式放再生产线中,会出现一个问题:如果线程A首次访问,发现为null则去创建一个新的,再创建的过程中,线程B也访问,又创建了一个。这样就违背了单例原创,一个系统中则存在好几个单例,如何解决这个问题呢,有两个方案,饿汉和懒汉。

    饿汉

    在声明的时候就初始化,不给多线程而带来的初始化时间差机会。

    public class EagerSingleton {
        private static final EagerSingleton instance =new EagerSingleton;
        private EagerSingleton(){}
        public static EagerSingleton getInstance(){
            return instance;
        }
    }
    
    

    懒汉

    使用同步锁synchronized

    package method.Singleton;
    
    public class LazySingleton {
        
        private static LazySingleton instance = null;
        private LazySingleton(){}
        
        public static LazySingleton getInstance(){
            if(instance == null){
                 synchronized(LazySingleton.calss){
                    instance = new LazySingleton();
                }
            }
            return instance;
        }
    }
    
    
    个人小站:http://jun10ng.work/ 拥抱变化,时刻斗争,走出舒适圈。
  • 相关阅读:
    leetcode 190 Reverse Bits
    vs2010 单文档MFC 通过加载位图文件作为客户区背景
    leetcode 198 House Robber
    记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
    逆序数2 HDOJ 1394 Minimum Inversion Number
    矩阵连乘积 ZOJ 1276 Optimal Array Multiplication Sequence
    递推DP URAL 1586 Threeprime Numbers
    递推DP URAL 1167 Bicolored Horses
    递推DP URAL 1017 Staircases
    01背包 URAL 1073 Square Country
  • 原文地址:https://www.cnblogs.com/Jun10ng/p/12372145.html
Copyright © 2011-2022 走看看