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; } }