今天自己简单地整理了一下单例设计模式,这是一个很基本的程序设计模式,在开发中经常被用到,所谓的单例设计模式,我自己的理解是简单粗暴地告诉你,只有我能创建我自己的对象,你们想要操作我类里面的东西,只能通过我创建地这个对象,而且有且只有一个对象,这也就同时保证了数据的共享和线程安全,那么如何保证只有我自己才能创建对象,且只能创建一个对象,也就是对象的唯一性呢?我们直接贴上代码来进行简单明了的说明:
ps:纯属个人愚见,大神勿喷。
单例设计模式有两种,分别是饿汉式和饱汉式,具体含义,我们看名字就能分辨出来。所谓饿汉式,就像生活中一个饿了很久的人,只要是吃的东西,那我不管三七二十一,先吃了再说,这个在代码中的体现就是类一加载我就马上创建本类对象;而饱汉式呢,就是我平时生活幸福美满,那我对于吃东西的要求自然是有需要的时候再吃,这在代码中的体现就是类加载的时候我只声明本类对象的对象名,并不会直接去创建它,而只有其他程序来调用我对外提供的方法,也就是需要我的时候,我再创建。
1 public class 饿汉式 {
2 public static void main(String[] args) {
3 //Single s1=new Single();会发现根本创建不了这个类对象,因为构造方法私有化了
4 Single s1=Single.getInstance();
5 Single s2=Single.getInstance();
6 System.out.println(s1==s2);//这里可以很明显看到输出true,说明两个对象的地址值是一样的,也就是说获得的其实是同一个对象!
7 }
8 }
9
10 class Single{
11
/*
12 * 在这里创建一个本类对象,这也是唯一的一个对象
13 */
14 private static Single single=new Single();
15
16 /*
17 * 将构造方法私有化,就是为了防止创建对象,而这正是保证对象唯一性的关键所在
18 */
19 private Single(){}
20
21 /*
22 * 这里对外提供了一个获得本来唯一对象的方法,其他程序调用这个方法就能获得本类对象,
23 * 而因为已经将构造方法私有化,那么其他程序只能通过类名进行调用,所以需要将方法用static修饰
24 * 而静态方法内的成员变量也必须是静态修饰的,所以需要将之前定义的本类对象也用static修饰
25 * 但是之前创建的额对象一旦使用了静态修饰,那么其他程序又可以通过类名.属性名的方法去创建本类对象了,这破坏了对象唯一性
26 * 所以我们需要将本类对象静态并且私有化,这样其他程序只能通过对外提供的方法获得本类对象,而这个对象时唯一的,所以就保证了本类对象的唯一性
27 */
28 public static Single getInstance(){
29 return single;
30 }
31 }
public class 懒汉式 {
public static void main(String[] args) {
Single s1=Single.getInstance();
Single s2=Single.getInstance();
System.out.println(s1==s2);
}
}
class Single2{
private static Single2 single2=null;
private Single2(){}
/*
* 懒汉式跟懒汉式唯一的区别在于这里,饿汉式是在本类一加载,就立马创建本类对象(也就是唯一的那个对象),这个很形象的就是一个饿了很久的人,一见到东西不管三七二十一先吃
* 而懒汉式就讲创建对象的语句放到了对外提供的方法体内,类加载的时候,他只是声明了一个本类类型的变量,而真正创建对象的操作是在其他程序调用这个方法的时候,这很形象地就像一个懒汉,有东西我先不吃,我等饿了再吃
*/
public static Single2 getInstance(){
If(s==null){
Synchronized(Single2.class){
If(single==null){
single2=new Single2();
}
}
}
return single2;
}
}
/*
但是懒汉式是存在线程安全隐患的,如果多个线程同时调用方法,会创建不同的变量,所以我们需要给创建对象的代码加锁,用来保证只能有一个线程创建对象,这也是面试过程中会遇到的比较多的问题
*/
其实搞懂单例设计模式并不是一个特别难的事情,最主要思想是我们如何去保证本类对象的唯一性,而这些,我都在代码中给出注释说明了。
|
|