• 单例模式 饿汉与懒汉


    单例模式

    就像任务管理器一样,只能由一个实例,你不能同时打开两个任务管理器,所以单例模式的对象不可以再外部通过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/ 拥抱变化,时刻斗争,走出舒适圈。
  • 相关阅读:
    Linux操作系统 (RHEL 7/CentOS 7)
    (OK) 运行cBPM in Fedora23
    (OK) 运行cBPM—Fedora23
    (OK) Install codeblocks_16.01 on Fedora23
    (OK) Fedora23——Docker——CORE—testing
    (OK) CORE nodes access Internet—虚拟节点访问互联网—commands
    (OK-half) Fedora23——Docker——CORE—testing
    (OK) running imunes in Fedora 23
    (OK-HALF) To Find a Rogue DHCP Server—tcpdump/dhclient—nmap
    (OK) shell script—Find a Rogue DHCP Server—tcpdump/dhclient—nmap
  • 原文地址:https://www.cnblogs.com/Jun10ng/p/12372145.html
Copyright © 2020-2023  润新知