Java设计模式-单例模式
来源:互联网 发布:weex playground 源码 编辑:程序博客网 时间:2024/06/08 18:20
确保某个类有且仅有一个对象的场景,避免产生多个对象消耗过多资源。例如:访问io和数据库资源,这时就要考虑使用单例模式。
2:UML图
关键点:
1:构造方法为private(该类不能通过new的方式产生对象)
2: 通过静态方法或枚举返回单例对象
3:确保在多线程环境下,产生的对象只有一个
4:确保单例对象在反序列化时,不会产生新对象
3:代码举例
3.1 饿汉模式:
public class Singleton2{private Singleton2(){}private static final Singleton2 single2=new Singleton2();public static Singleton2 getInSingleton2(){return single2;}}
1)原始:
public class Singleton {//1: 懒汉模式,在类第一次调用自己时实例化自己private Singleton(){}private static Singleton singleton=null;/** * 有线程安全问题 * @return */public static Singleton getInstance(){if(singleton==null){ singleton=new Singleton();}return singleton;}}
2)解决方案1:
public class Singleton {//1: 懒汉模式,在类第一次调用自己时实例化自己private Singleton(){}private static Singleton singleton=null;/** * 好像性能有些问题 * @return */public static synchronized Singleton getInstance(){if(singleton==null){singleton=new Singleton();}return singleton;}}
3)解决方案2:DCL-双重检查锁定
public class Singleton {//1: 懒汉模式,在类第一次调用自己时实例化自己private Singleton(){}private static Singleton singleton=null;public static Singleton getInstance(){if(singleton==null){synchronized (Singleton.class) {if(singleton==null){singleton=new Singleton();//1}}}return singleton;}}
双重检查锁定(DCL)-存在指令重排序的问题:
注释1处:可能指令重排序,导致有一个线程会获取一个初始化一半的singleton,应该private volatile static Singleton singleton=null;
singleton=new Singleton();
a: 给Singleton实例分配堆内存
b: 调用Singleton构造函数
c: 将singleton指向分配的内存空间
b依赖于a,c依赖于a,b,c之间无依赖,导致执行顺序:
a-b-c: 没毛病
或
a-c-b:
刚好执行完a-c,这时,线程切换到别的线程,这时singleton非空,执行会有问题,不好排查。
private volatile static Singleton singleton=null;
public class Singleton1{private static class LazyHolder{private static final Singleton1 INSTANCE=new Singleton1();}private Singleton1(){}public static final Singleton1 getInstance(){return LazyHolder.INSTANCE;}}
3.3 枚举方式
public enum SingletonEnum { INSTANCE; private Person person=new Person(); public Person getPerson() { return person; } public class Person{ }}
3.4 反序列化
public class Singleton implements Serializable{private static final long serialVersionUID=-1L;protected Object readResolve() {return singleton;}
public class SaveAndRead {public static void main(String[] args){Singleton mSingleton= Singleton.getInstance();System.out.println("序列化前对象:"+mSingleton.hashCode());try {FileOutputStream fos=new FileOutputStream(new File("123.txt"));ObjectOutputStream oos =new ObjectOutputStream(fos);oos.writeObject(mSingleton);oos.close();fos.close();} catch (Exception e) {e.printStackTrace();}try {FileInputStream fis =new FileInputStream(new File("123.txt"));ObjectInputStream ois =new ObjectInputStream(fis);Singleton singleton=(Singleton)ois.readObject();ois.close();fis.close();System.out.println("反序列化后对象:"+singleton.hashCode());} catch (Exception e) {} }}
3.5 容器单例模式
public class SingletonManager{private static Map<String, Object> objMap=new HashMap<String, Object>();private SingletonManager(){}public static void addService(String key, Object instance){if(!objMap.containsKey(key)){objMap.put(key, instance);}} public static Object getService(String key){return objMap.get(key);}}
4:android中的单例模式
4.1 frameworks/base/core/java/android/view/accessibility/AccessibilityManager.java
/** * Get an AccessibilityManager instance (create one if necessary). * * @param context Context in which this manager operates. * * @hide */ public static AccessibilityManager getInstance(Context context) { synchronized (sInstanceSync) { if (sInstance == null) { final int userId; if (Binder.getCallingUid() == Process.SYSTEM_UID || context.checkCallingOrSelfPermission( Manifest.permission.INTERACT_ACROSS_USERS) == PackageManager.PERMISSION_GRANTED || context.checkCallingOrSelfPermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED) { userId = UserHandle.USER_CURRENT; } else { userId = UserHandle.myUserId(); } sInstance = new AccessibilityManager(context, null, userId); } } return sInstance; }
4.2 frameworks/base/core/java/android/text/Editable.java
- java 设计模式,单例设计模式
- java设计模式-单例设计模式
- java设计模式-单例设计模式
- Java设计模式 单例设计模式
- Java设计模式------单例设计模式
- java设计模式----->单例设计模式
- java设计模式:单例设计模式
- java设计模式-----单例设计模式
- Java设计模式----单例设计模式
- java设计模式-单例设计模式
- java设计模式:单例设计模式
- java 设计模式-单例设计模式
- Java设计模式--单例设计模式
- java设计模式---单例设计模式
- Java设计模式-单例设计模式
- JAVA设计模式:单例设计模式
- java-单例设计模式
- Java设计|单例模式
- centos6.5下使用yum完美搭建LNMP环境(php5.6)
- Java四种线程池的使用
- 桶排序删除数组重复元素,然后从小到大排序输出。
- 朴素贝叶斯算法
- Java设计模式之简单工厂模式
- Java设计模式-单例模式
- Redis学习(二):Redis的配置文件详解
- 润乾报表echarts统计图省份地图设置
- PHP 中 Redis 的常用方法
- 51nod 1831 小C的游戏
- POJ 2353 Ministry(双向动规 输出过程)
- 堆排序
- STL介绍
- ios UINavigationBar 高度修改