单例设计模式

1:单例模式(面试)

单例模式:单一的实例.保证类在内存中只有一个对象.
举例:

①windows的打印费服务.网站的计数器.(如果一个网站统计访问量有多个计数器,就会有问题.)
②Java中的应用:数据库连接池,Runtime这个类.

2.如何保证类在内存中只有一个对象?

A:把构造方法私有,为了不让外界创建对象.
B:在类中创建 一个对象.(有一个对象,还是要创建它)
C:通过一个公共的访问方式,给外界一个入口.(否则外界根本就无法访问到)

 

3.饿汉式单例模式:

Student.java

单例设计模式
 1 public class Student {
 2     //为了不让外界访问,我们把构造方法私有.
 3     private Student(){
 4         
 5     }
 6     //创建一个对象
 7     //为了满足静态方法访问,这里也必须加一个静态修饰符static(暂时先不加private,慢慢引入private)
 8     //static Student s = new Student();
 9     private static Student s = new Student();
10     
11     //提供一个公共的访问方式
12     //(访问这个方法可以通过Student类的对象,但是构造方法私有化了无法让外界访问)
13     //所以为了让外界直接访问,只能让这个方法静态.
14     public static Student getStudent(){
15         //比如说我有t1和t2同时来访问,那么这个时候.拿的都是上面new的
17         return s;
18         //如果此时上面的Student s = new Student();不用静态修饰,报错.内容如下
19         //Cannot make a static reference to the non-static field s
20         //一个静态的上下文,不能有一个非静态的变量.
21         //所以为了满足静态方法访问,new Student的时候必须用static修饰.
22     }
23     
24     public void show(){
25         System.out.println("我爱java");
26     }
27 }
单例设计模式

测试类:StudentTest.java

单例设计模式
 1 public class StudentTest {
 2     public static void main(String[] args) {
 3         /*
 4         Student s1 = new Student();
 5         Student s2 = new Student();
 6         System.out.println(s1 == s2);//false
 7         */
 9         //由于成员变量是被静态static修饰的,前面没有加访问修饰符,默认是default外界也可以通过类名访问的.
10         //Student.s = null;
11         //这样的话下面运行s1.show()的时候就会报java.lang.NullPointerException
12         //为了不让外界访问s,就再在new 的时用private修饰. 这样此时
13                     
14         //通过单例模式获取对象并调用方法.
15         
16         Student s1 = Student.getStudent();
17         Student s2 = Student.getStudent();
18         System.out.println(s1 == s2);//true
19         
20         s1.show();
21         s2.show();
22     }
23 }
单例设计模式

4:懒汉式单例模式(想用的时候再用)

懒汉式有一个非常重要的思想----延迟加载思想.
我们什么时候需要,你就什么时候给. 这个思想在Hibernate和Spring中都用了这个思想.  特别是Hibernate框架中的lazy....

Teacher.java

单例设计模式
 1 public class Teacher {
 2     // 为了不让外界创建对象,把构造方法私有.
 3     private Teacher() {
 4     }
 5 
 6     // 本类创建一个对象.
 7     // 加static是为了保证静态方法可以访问.
 8     // 加private是为了保证外界不能直接访问
 9     private static Teacher t = null;
10 
11     // 提供公共的访问方式.
12     //synchronized是为了解决懒汉式多线程不安全加上的.
13     //被同步的代码,在某一时刻只能被一个线程访问.
14     public synchronized static Teacher getTeacher() {
15                 /*
16                 比如说我有t1和t2同时来访问,那么这个时候.
17                 当t1进来后,判断这个时候t是null
18                 所以,t1就进去执行if所控制的语句.
19                 但是注意了,由于线程的随机性.可能当t1刚进去要执行if说控制的语句.
20                 发现,这个时候t还是null,所以,t2也去执行if所控制的语句了.
21                 那么将来就会有多个对象被创建.
22                 */
23         // 当外界需要使用它,就在这里new一个.
24         if (t == null) {
25             // 只有第一次访问这里的时候才进入if语句new一个对象.
26             // 第二次的时候因为第一次已经new了一个Teacher,并且Teacher是用static修饰
27             // static修饰的是共享的.有值了,就不再进入if了.
28             t = new Teacher();
29         }
30         return t;
31     }
32 
33     // 写了一个方法
34     public void love() {
35         System.out.println("老师爱学生");
36     }
37 }
单例设计模式

TeacherTest.java

单例设计模式
 1 public class TeacherTest {
 2     public static void main(String[] args) {
 3         Teacher t1 = Teacher.getTeacher();
 4         Teacher t2 = Teacher.getTeacher();
 5         System.out.println(t1 == t2);// true
 6 
 7         t1.love();
 8         t2.love();
 9     }
10 }
单例设计模式

5:那么我们在开发中到底使用谁呢?

一般开发中使用第一种方案(饿汉式) 
原因是:
前提:多线程安全问题.
面试的时候会面试懒汉式. 并且,请注意,面试懒汉式,主要是面试下面几个问题:
A:延迟加载思想.
B:线程安全问题.
a:线程安全问题是怎么产生的.
b:线程安全问题是怎么解决的.

6:其实在JDK中提供的类中,已经有单例模式的应用.是谁呢?Runtime类.

附上JDK中关于Runtime类的源码:

Runtime.java

单例设计模式
 1 public class Runtime {
 2     //这就是一个饿汉式的应用.
 3     private static Runtime currentRuntime = new Runtime();
 4     
 5     public static Runtime getRuntime() { 
 6         return currentRuntime;
 7     }
 8     
 9     private Runtime() {}        
10         
11 }    
单例设计模式

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/4086250.html,如需转载请自行联系原作者

上一篇:Renascence架构介绍——目录


下一篇:客户至上!OA产业服务能力有待提升