二十四种设计模式:单例模式(使用频率4个星,共5星)

public class TaskManager{
    private static taskManager=null;
    private TaskManager(){    //设置为私有构造,确保不能被外部实例化
            
    }
    
    public static TaskManager getInstance(){
        if(taskManager==null){
                taskManager=new TaskManager();
                }
        return taskManager;
    }
}

 

上面代码就是单例模式的一个原型,存在的问题:如果TaskManager构造方法中要进行大量的初始化工作,需要一段时间来创建 TaskManager 对象,当多个线程同时进行初始化,都执行到了if(taskManager==null){ 这一行判断都为true,当第一个线程创建成功了,第二线程还会接着创建
最终导致创建了多个对象,这违备了单例模式的初衷,也导致系统发生运行异常。

解决该问题,可以使用饿汉模式、和懒汉模式
饿汉模式代码:

public class TaskManager{
    private static final TaskManager taskManager=new TaskManager();
    private TaskManager(){}
    public static TaskManager getInstance(){
        return taskManager;
    }
}

 


这种模式是不是很简单,缺点当类被加载是对象就会被创建不管你需不需要。
懒汉模式也就是第一种模式,下面我们来解决线程并发问题

public class TaskManager{
    private static taskManager=null;
    private TaskManager(){    //设置为私有构造,确保不能被外部实例化
            
    }
    
    public static TaskManager getInstance(){
        if(taskManager==null){
                taskManager=new TaskManager();
                }
        return taskManager;
    }
}

 


解决线程并发:

public class TaskManager{
    private static taskManager=null;
    private TaskManager(){    //设置为私有构造,确保不能被外部实例化
            
    }
    
    public static TaskManager getInstance(){
        if(taskManager==null){
            synchrozied(TaskManager.class){
                    if(taskManager==null){
                        taskManager=new TaskManager();
                    }
                }
        }
        return taskManager;
    }
}

 


必须使用双重验证,如果删除getInstance方法中外层的if(taskManager==null),适必会增加系统的开销,每进入该方法都会进行锁定,如果删除内层的if(taskManager==null)就可能会出现多个实例情况,多个线程同时进行访问执行到synchrozied(TaskManager.class)都在待,当第一个线程创建成功后,释放锁,第二个线程就会马上进入synchrozied(TaskManager.class)开始创建,如果不进行if(taskManager==null)就可能再次创建对象,这就违备了单例模式初衷,导致系统运行异常。

饿汉模式不管你用与不用都会占用内存资源,懒汉模式会带来性能上的损耗,有没有一种更好的兼容模式呢:内部静态类模式

public class TaskManager{
    private TaskManager(){}
    private static class MyInstance{
        private static final myInstance =new MyInstance();
    }
    public static MyInstance getInstance(){
        return MyInstance.myInstance;
    }
}

 

posted on 2018-02-06 21:52  lvlv岁月流逝  阅读(206)  评论(0编辑  收藏  举报

导航