单例设计模式
---------------------- QQ:371524846 期待与您交流! ----------------------
设计模式:
解决某一类问题最行之有效的方法
Java中23种设计模式:
单例设计模式:解决一个类在内存只存在一个对象。
一、保证对象唯一的思想及其实现:
1.为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象。
2.还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三部怎么用代码体现呢?
将构造函数私有化。
在类中创建一个本类类型对象。
提供一个方法可以获取到该对象。
注意:对于事物该怎么描述,还怎么描述。当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
二、单例设计模式的具体表现形式:
1、先初始化对象,类一进内存就加载,称为:饿汉式
SingleHungry类一进内存,就已经创建好了对象。
eg:
1 class SingleHungry{ 2 private String name; 3 public void setName(String name){ 4 this.name=name; 5 } 6 public String getName(){ 7 return name; 8 } 9 private static SingleHungry s=new SingleHungry(); 10 private SingleHungry(){} 11 public static SingleHungry getInstance(){ 12 return s; 13 } 14 } 15 public class SingleTest{ 16 public static void main(String[] args) { 17 SingleHungry s1 = SingleHungry.getInstance(); 18 SingleHungry s2 = SingleHungry.getInstance(); 19 s1.setName("南贤俊"); 20 System.out.println(s2.getName()); 21 } 22 }
2、类进内存,对象还有没存在,只getInstance方法被调用时,才初始化对象,也叫做对象的延时加载,成为:懒汉式
对于第二种懒汉式的单例设计模式,会出现一些小小的问题,当一个线程调用时,是没什么问题的,如果多个线程调用此种方式,那么就会出现问题。所以用到同步锁。
SingleLazy类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
eg:
1 class SingleLazy { 2 private String name; 3 public void setName(String name){ 4 this.name=name; 5 } 6 public String getName(){ 7 return name; 8 } 9 private static SingleLazy s=null; 10 private SingleLazy(){} 11 public static SingleLazy getInstance(){ 12 if(s==null){ 13 synchronized(SingleLazy.class){ 14 if(s==null) 15 s=new SingleLazy(); 16 } 17 } 18 return s; 19 } 20 } 21 public class SingleTest{ 22 public static void main(String[] args) { 23 SingleLazy s1 = SingleLazy .getInstance(); 24 SingleLazy s2 = SingleLazy .getInstance(); 25 s1.setName("南贤俊"); 26 System.out.println(s2.getName()); 27 } 28 }
运行的结果是:南贤俊;这是因为s1和s2引用的是同一个对象,所以符合条件。
比如说,当A调用时,当读到if(s1==null) 时,可能就停在这了,然后cpu再调用B,B也读到if(s1==null)这停下了,cpu再切换到A,接着创建一个对象,A就执行完了;
之后B也向下执行,又创建一个对象;此时,对象就不唯一了,就破坏了对象的唯一性的初衷。那么解决方案是这样的:
这利用了锁的机制。synchronized是java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
这涉及到了多线程的问题。在这个例子中,比如说,当A调用时,当读到第二个if(s1==null) 时,可能就停在这了,然后cpu再调用B,
B读到第一个if(s1==null)这停下了,因为加上synchronized后,A进去就相当于将其他的调用锁在外面的语句上了,要先执行完A,那么A执行完后,就已经创建了一个对象;
当B再读到第二个if(s1==null)的时候不符合就直接结束了。如果再有其他C或D等调用的时候,就直接不符合第一个(s1==null)的条件,所以直接返回s。
---------------------- QQ:371524846 期待与您交流! ----------------------