zoukankan      html  css  js  c++  java
  • 并发(五)-单例模式

    这里系统的说一下单例模式。

    本文参考的文章,地址如下:

    微信公众号:Java后端技术

    文章:Java多线程编程-(12)-单例模式几种写法的错与对

    作者:徐刘根

    主要是四大类:饿汉、懒汉、双重校验锁DCL、

    1.饿汉模式

    示例如下:

     1 public class Singleton {
     2 
     3     /*为了防止外部访问,所以实例是private的
     4     为了在static方法中访问,所以必须是static
     5     至于为什么,叫饿汉模式。我想,因为在程序走到下面这一行时,
     6     会初始化,调用构造方法。在没有调用getInstance方法时,就创建好了实例。
     7     因为,可能叫做饿汉模式吧*/
     8     private static Singleton singleton = new Singleton();
     9     
    10     private Singleton() {
    11         System.out.println("666");
    12     }
    13     public static Singleton getInstance() {
    14         return singleton;
    15     }
    16 }

    2.懒汉模式

    示例如下:

     1 public class SingletonByLazy {
     2 
     3     private static SingletonByLazy singleton;
     4     
     5     /*这里必须是private修饰符,否则,就可以new多个对象,这是单例模式最基本的保证*/
     6     private SingletonByLazy() {}
     7     
     8     /*需要注意的是,必须加上synchronized关键字。否则会导致对象的访问变得不安全。
     9      * 饿汉的优点是延迟加载,在你需要的时候进行加载。缺点是必须使用同步*/
    10     public static synchronized SingletonByLazy getInstance() {
    11         if (singleton == null) {
    12             singleton = new SingletonByLazy();
    13         }
    14         return singleton;
    15     }
    16 }

    3.双重校验锁DCL

    代码比上面两种多一些,绕一些,但是思想还是值得学习的嘛!看下面的例子:

     1 public class SingletonByDCL {
     2 
     3     /*这里切记,volatile关键字不可以缺少。
     4      * 不然会因为指令重排,导致在第一个判空时,将未初始化的对象返回。*/
     5     private volatile static SingletonByDCL singleton;
     6     
     7     /*这里必须是private修饰符,否则,就可以new多个对象,这是单例模式SingletonByLazy.java最基本的保证*/
     8     private SingletonByDCL() {}
     9     
    10     /*需要注意的是,必须加上synchronized关键字。否则会导致对象的访问变得不安全。
    11      * 饿汉的优点是延迟加载,在你需要的时候进行加载。缺点是必须使用同步*/
    12     public static SingletonByDCL getInstance() {
    13         if (singleton == null) {
    14             synchronized (SingletonByDCL.class) {
    15                 if (singleton == null) {
    16                     singleton = new SingletonByDCL();
    17                 }
    18             }
    19         }
    20         return singleton;
    21     }
    22 }

    4.静态内部类

     1 public class SingletonByStaticClass {
     2 
     3     /*通过类加载机制,保证创建单一对象*/
     4     private static class SingletonHolder {
     5         private static final SingletonByStaticClass single = new SingletonByStaticClass();
     6     }
     7     
     8     private SingletonByStaticClass() {}
     9     
    10     /*对于JAVA的加载机制来说,当第一次访问类的静态字段时,会触发类的加载*/
    11     public static SingletonByStaticClass getInstance() {
    12         return SingletonHolder.single;
    13     }
    14 }

    接下来,我要单独说一下static关键字。因为非常重要。

    小例子:

     1 public class Test {
     2 
     3     public void method01(){
     4         System.out.println("method01");
     5     }
     6     
     7     public static void method02(){
     8         System.out.println("method02");
     9     }
    10     
    11     public static void main(String args[]){
    12         new Test().method01();
    13         method02();
    14     }
    15 }
    16 
    17 
    18 执行结果:
    19 method01
    20 method02

    例子很简单,但是要说明的地方是:静态方法中不能直接调用非静态方法。

    为什么呢?首先static的成员是在类加载的时候初始化的,而非static的成员是在创建对象的时候初始化的。先后顺序是,先加载才能初始化。那么加载的时候,初始化static成员,非static成员是在创建对象的时候初始化的。也就是说,static属于类,而非static属于对象。

    下面说static的特点:

    1.随着类的加载而加载,随着类的消失而消失(能消失吗? 这里我有疑问,有待验证)。

    2.静态先存在,对象后存在。

    3.被所有对象共享。

    4.直接调用

    使用时注意事项:

    1.静态方法只能方法静态成员。

    2.静态方法中不能使用super  this 关键字。原因呢,上方的解释,懂了的话,这一点自然就明白了。

    3.主函数是静态的。

    就说这么多了。。。

  • 相关阅读:
    Object Modeling
    数据库的比较
    关系数据库与非关系数据库
    结构化查询语言-SQL
    SQLite
    acid (数据库事务正确执行的四个基本要素的缩写)
    UITableView设计思想 考察
    复杂软件的考虑点与UITableView
    设计模式与哲学
    复杂对象的组装与创建-建造者模式
  • 原文地址:https://www.cnblogs.com/lihao007/p/7739836.html
Copyright © 2011-2022 走看看