zoukankan      html  css  js  c++  java
  • java单件模式

    意图:确保一个类只有一个实例,并提供一个全局访问点
    适用性:
    1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
    2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时
    结构图:

    实例:

     1 package com.test.patten.singleton;
     2 
     3 public class Singleton {
     4     private static Singleton instance;
     5     private String message;
     6 
     7     private Singleton(){
     8         message ="message被初始化";
     9         System.out.println(System.currentTimeMillis());
    10     }
    11     
    12     public static Singleton getInstance() {
    13         if(instance == null){
    14             instance =  new Singleton();
    15         }
    16         return instance;
    17     }
    18     
    19     public String getMessage() {
    20         return message;
    21     }
    22 
    23     public void setMessage(String message) {
    24         this.message = message;
    25     }
    26 }
     1 package com.test.patten.singleton;
     2 
     3 public class Client {
     4     public static void main(String args[]){
     5         Singleton singleton = Singleton.getInstance();
     6         System.out.println(singleton.getMessage());
     7         
     8         //第二次获取
     9         Singleton singleton2 = Singleton.getInstance();
    10         System.out.println(singleton2.getMessage());
    11     }
    12 }

    输出:

    1362036694546
    message被初始化
    message被初始化

    从输出可以看出,第二次获取时,没有新建实例
    考虑到并发,在getInstance()方法加上synchronized关键字修饰,但可能会使性能下降,可以有以下两种方式
    1、使用'饿汉式'创建实例,而不用'懒汉式'的做法

     1 package com.test.patten.singleton;
     2 
     3 public class Singleton {
     4     private static Singleton instance = new Singleton();
     5     private String message;
     6 
     7     private Singleton(){
     8         message ="message被初始化";
     9         System.out.println(System.currentTimeMillis());
    10     }
    11     
    12     public static Singleton getInstance() {
    13         return instance;
    14     }
    15     
    16     public String getMessage() {
    17         return message;
    18     }
    19 
    20     public void setMessage(String message) {
    21         this.message = message;
    22     }
    23 }

    利用这个做法,依赖JVM在加载这个类时马上创建此唯一的单件实例,JVM保证在任何线程访问instance静态变量之前,一定先创建此实例
    2、利用双重检查加锁,在getInstance()中减少使用同步,优化'懒汉式'初始化

     1 package com.test.patten.singleton;
     2 
     3 public class Singleton {
     4     private volatile static Singleton instance;
     5     private String message;
     6 
     7     private Singleton(){
     8         message ="message被初始化";
     9         System.out.println(System.currentTimeMillis());
    10     }
    11     
    12     public static Singleton getInstance() {
    13         if(instance == null){
    14             synchronized (Singleton.class) {
    15                 if(instance == null){
    16                     instance = new Singleton();
    17                 }
    18             }
    19         }
    20         return instance;
    21     }
    22     
    23     public String getMessage() {
    24         return message;
    25     }
    26 
    27     public void setMessage(String message) {
    28         this.message = message;
    29     }
    30 }

    当关注性能时,这样的做法可以大大减少getInstance()耗费的时间
    注意点:
    1、单件模式需要一个私有的构造器、一个静态方法、一个静态变量
    2、确定在性能和资源上的限制,然后小心的选择适当的方案以解决多线程的问题

  • 相关阅读:
    idea快捷键总结
    将对象序列化和反序列化
    在Springmvc中获取properties属性
    配置springmvc在其他类中(spring容器外)获取注入bean
    redis学习之三配置文件redis.conf 的含义
    redis学习之二from github
    敏捷开发方法XP的12个最佳实践
    IIS-网站发布之后访问HTTP 错误 403.14
    IIS-将iis直接指向.net代码会出现错误
    HTTP 错误 500.24
  • 原文地址:https://www.cnblogs.com/ikuman/p/2935531.html
Copyright © 2011-2022 走看看