android 设计模式 单例(Singleton)模式

来源:互联网 发布:tcp监听端口阻塞 编辑:程序博客网 时间:2024/06/06 06:58

android 设计模式 单例(Singleton)模式

设计模式:描述了软件设计过程中某一类常见问题的一般性的解决方案。(设计模式:就是灵活应用抽象类、接口解决常用问题)
每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。

面向对象设计模式:
描述了面向对象设计过程中、特定场景下、类与相互通信的对象之间常见的组织关系。
整个设计模式贯穿一个原理:
1、面对接口编程,而不是面对实现.
2、目标原则是: 降低耦合,增强灵活性.

设计模式:创建型模式 结构型模式 行为模式

volatite关键字:(多线程)
volatile int value
每次都都是value 主内存——缓存,从而保证值能实时更新
synchronized关键字:
加锁,多个线程同时访问同个变量,那应该给这个变量加个锁,第一个线程访问时,其他线程等待第一线程执行完才能访问
内存同步(一致性),且保证线程互斥(互斥性)。

对一个全局对象或者类加锁时,对该类的所有对象都起作用

synchronized作用于静态方法和非静态方法的区别:
非静态方法:
给对象加锁(可以理解为给这个对象的内存上锁,注意 只是这块内存,其他同类对象都会有各自的内存锁),这时候
在其他一个以上线程中执行该对象的这个同步方法(注意:是该对象)就会产生互斥
静态方法:
相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块
内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥

static关键字:
声明变量在主内存上的唯一性,不能保证缓存与主内存变量值的一致性;除非变量的值是不可变的,即再加上final的修饰符,否则static声明的变量,不是线程安全的。
可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。

单例模式 Singleton Patter

应用场景:
1、需要保证操作的一致性,即间断性的操作时,每一次的操作结果会保留,下一次继续从上一次的间断点开始(I/O流,数据库链接、缓冲区等)。
2、逻辑上只能有一个实例
3、频繁的创建和使用消耗的资源较大。(I/O流、数据库链接)

单例模式的实现:
1、构造函数private化(即不对外开放)
2、通过一个静态方法或者枚举返回单例对象(通过public static方法返回)
3、确保单例类的对象有且只有一个,尤其是在多线程的环境下
4、确保单例类对象在反序列化时不会重新构建对象

单例模式创建方式:
饿汉、懒汉、双重校验锁、静态内部类和枚举

//饿汉public class Singleton {    private static Singleton instance = new Singleton();  //应用启动时加载并初始化    private Singleton() {}    public static Singleton newInstance() {       return instance;    }}//懒汉public class Singleton {    private static volatile Singleton instance = null;      private Singleton() {}    public static Singleton newInstance() {       if(instance == null){          instance = new Singleton(); //延迟加载       }       return instance;    }}//双重校验锁(多线程)public class Singleton {    private static volatile Singleton instance = null;      private Singleton() {}    public static Singleton newInstance() {       if(instance == null){          synchronized(Singleton.class){ // 类锁             if(instance == null){                instance = new Singleton();             }          }       }       return instance;    }}//静态内部类(多线程)-- android系统中应用较多public class Singleton {    //静态内部类,JVM装载该内部类时才会去创建Singleton,实现懒汉式的延迟加载和线程安全    private static class SingletonHolder {        public static Singleton instance = new Singleton();    }    private Singleton() {}    public static Singleton newInstance() {        return SingletonHolder.instance();    }}public enum Singleton{    instance; // 枚举元素,Singleton的实例}//泛型单例类public class Student {    private int age;    private String name;    private String gender;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getGender() {        return gender;    }    public void setGender(String gender) {        this.gender = gender;    }}public class City {    private String name;    private String addr;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAddr() {        return addr;    }    public void setAddr(String addr) {        this.addr = addr;    }}public class Singleton<T> {    private static final ConcurrentMap<Class, Object> map = new ConcurrentHashMap<>();    public static<T> T getSingleton(Class<T> c){ //Class<T>代表类型T所对应的类           Object ob = map.get(type);             try{                  if(ob==null){                       synchronized(map) {                           // 通过Class<T>类型变量c来创建具体类类型的对象实例                           ob = c.newInstance();                            map.put(type,ob);                       }                  }             }catch(InstantiationException e) {                  e.printStackTrace();             }catch(IllegalAccessException e) {                  e.printStackTrace();             }           return (T) ob;      }    public static<T> void Remove(Class<T> c){           map.remove(c);         }}public class Test0{    public void inputTest() {           Student student = Singleton.getSingleton(Student.class);           student.setName("王小明");           student.setAge(3);           City city = Singleton.getSingleton(City.class);           city.setName("广州市");           city.setAddr("市桥工业路");        }  }public class Test1{    public static void main(String[] args) {       Test0 test = new Test0();       test.inputTest();           Student student = Singleton.getSingleton(Student.class);       City city = Singleton.getSingleton(City.class);           System.err.println(city.getName()+city.getAddr());        } }