设计模式一-单例设计模式
设计模式一--单例设计模式
一、定义
Singleton Pattern:
确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
二、分类
饿汉式单例类:类加载时就进行对象的实例化
懒汉式单例类:第一次引用类时,才进行对象的实例化。
三、核心代码
3.1 饿汉式
class Singleton{ private static Singleton m_instance=new Singleton(); //构造方法私有,保证外界无法直接实例化 private Singleton(){ } //通过该方法获得实例对象 public static Singleton getInstances(){ return m_instance; } }
3.2 懒汉式
class Singleton2{ private static Singleton2 _instance=null; //构造方法私有,保证外界无法直接实例化 private Singleton2(){ } //通过该方法获得实例对象 public static Singleton2 getInstances(){ if(_instance==null){ _instance=new Singleton2(); } return _instance; } }
四、实例
4.1 饿汉式
class Singleton{ //成员变量x用来测试 int x; private static Singleton m_instance=new Singleton(); //构造方法私有,保证外界无法直接实例化 private Singleton(){ } //通过该方法获得实例对象 public static Singleton getInstances(){ return m_instance; } } public class SingletonPattern { public static void main(String[] args) { Singleton.getInstances(); Singleton.getInstances().x=1; } }
4.2 懒汉式
class Singleton2{ //成员变量x用来测试 int x; private static Singleton2 _instance=null; //构造方法私有,保证外界无法直接实例化 private Singleton2(){ } //通过该方法获得实例对象 public static Singleton2 getInstances(){ if(_instance==null){ _instance=new Singleton2(); } return _instance; } } public class SingletonPattern2 { public static void main(String[] args) { Singleton2.getInstances(); Singleton2.getInstances().x=1; System.out.println(Singleton2.getInstances().x=1); } }
五、单例模式的优缺点
5.1 优点
只有一个实例,减少内存开销,避免对资源的多重占用
可以设置全局访问点,优化和共享资源访问
5.2 缺点
无法创建子类
单例模式与单一职责原则有冲突
六、单例模式的使用场景
要求生成唯一序列号的地方
在整个项目中需要一个共享访问点和共享数据
创建一个对象消耗的资源太多
需要定义大量的静态常量和静态方法(如工具类)的环境
七、单例模式的应用实例
7.1 代码
1 class GlobalNum{ 2 3 private int num=0; 4 5 private static GlobalNum globalNum=new GlobalNum(); 6 7 // 8 9 public static GlobalNum getInstance() { 10 11 return globalNum; 12 13 } 14 15 //synchronized同步化 16 17 public synchronized int getNum() { 18 19 return num++; 20 21 } 22 23 public synchronized void setNum(int num) { 24 25 this.num = num; 26 27 } 28 29 } 30 31 32 33 class NumbelThread extends Thread{ 34 35 private String threadName; 36 37 public NumbelThread(String name) { 38 39 threadName=name; 40 41 } 42 43 44 45 public void run(){ 46 47 GlobalNum globalNum=GlobalNum.getInstance(); 48 49 //循环访问,输出访问次数 50 51 for (int i = 0; i < 5; i++) { 52 53 System.out.println(threadName+"第"+globalNum.getNum()+"次访问"); 54 55 56 57 } 58 59 } 60 61 } 62 63 64 65 public class SingletonDemo { 66 67 68 69 public static void main(String[] args) { 70 71 NumbelThread threadA=new NumbelThread("线程A"); 72 73 NumbelThread threadB=new NumbelThread("线程B"); 74 75 threadA.start(); 76 77 threadB.start(); 78 79 } 80 81 82 83 }
7.2 运行结果
线程A第0次访问
线程B第1次访问
线程A第2次访问
线程A第4次访问
线程B第3次访问
线程B第6次访问
线程B第7次访问
线程A第5次访问
线程B第8次访问
线程A第9次访问