设计模式一--单例设计模式

一、定义

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次访问