zoukankan      html  css  js  c++  java
  • [设计模式]单例设计模式

    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 }    
  • 相关阅读:
    数据结构(动态树):UOJ 207 共价大爷游长沙
    字符串(后缀自动机):NOI 2016 优秀的拆分
    数学(矩阵乘法):HDU 4565 So Easy!
    数据结构(线段树):NOI 2016 区间
    动态规划:NOI2013 快餐店
    图论(网络流):UVa 1659
    数学(矩阵乘法,随机化算法):POJ 3318 Matrix Multiplication
    数学(莫比乌斯反演):YY的GCD
    数学(莫比乌斯反演):HAOI 2011 问题B
    字符串(后缀自动机):USACO Dec10 恐吓信
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4086250.html
Copyright © 2011-2022 走看看