开发者社区> 游客sfvrpiloxozae> 正文

单例模式的应用(1)

简介: 单例模式的应用(1)
+关注继续查看

单例模式定义:


单例模式(Singlleton Pattern) 是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。单例模式是创建型模式。单例模式在现实生活中应用也非常广泛,例如公司CEO,部门经理等。J2EE标准中的ServletContext、ServletContextConfig等,Spring框架应用中ApplicationContext、数据库的连接池等也都是单例形式。


一、饿汉式单例

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。


优点:保证线程绝对安全,执行效率高,没有任何的锁


缺点:所有对象类加载的时候就实例化,系统初始化就会导致大量的内存浪费


//饿汉式单例类.在类初始化时,已经自行实例化 
public class Singleton {
    private Singleton() {}
    private static final Singleton single = new Singleton();
    //静态工厂方法 
    public static Singleton getInstance() {
        return single;
    }
}


二、懒汉式单例

优点:解决了饿汉式单例可能带来的内存浪费问题,节省内存

缺点:线程不安全的问题


//懒汉式单例类.在第一次调用的时候实例化自己 
public class Singleton {
    private Singleton() {}
    private static Singleton single=null;
    //静态工厂方法 
    public static Singleton getInstance() {
         if (single == null) {  
             single = new Singleton();
         }  
        return single;
    }
}


针对上述懒汉式单例存在线程安全,在多线程情况下,会生成多个实例,不满足单例模式;所以提出如下饿汉式线程安全单例模式

饿汉式线程安全


public class Singleton {
    private Singleton() {}
    private static Singleton single=null;
    //静态工厂方法 
    public static synchronized Singleton getInstance() {
         if (single == null) {  
             single = new Singleton();
         }  
        return single;
 }
}


  • 通过使用synchronized加锁时,在线程比较多的情况下,如果CUP分配压力上升,则会导致大批线程阻塞,从而导致程序性能下降。那么就引出了下边的双重检查锁的单例模式,(备注:synchronized是互斥锁,同一时刻只有一个线程能够访问方法)

双重检查锁


public class Singleton {
    private Singleton() {}
    private static volatile Singleton single=null;
    public static Singleton getInstance() {
         //第一层:双重检查锁的作用  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
            //第二层:是为了减少线程对同步锁的竞争
               if (singleton == null) {  
                  singleton = new Singleton(); 
               }  
            }  
        }  
        return singleton; 
    }


单例模式-双重检查加锁为什么需要加上volatile关键字?

双重检查锁单例模式为什么要用volatile关键字?


上述的双重检查锁虽然做了优化,但是仍然要使用synchronized关键字,对程序性能还是存在一定影响的。于是我们引入了如下的静态内部类形式的单例,从类初始化的角度来考虑,看如下代码采用了静态内部类的方式。


静态内部类

优点:写法优雅,利用了Java本身语法特点,性能奥,避免了内存浪费

缺点:能够被反射破坏


public class Singleton {  
    private static class LazyHolder {  
       private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
       return LazyHolder.INSTANCE;  
    }  
}  



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java单体应用 - 架构模式 - 03.设计模式-03.单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
171 0
【Android 应用开发】Activity 返回堆栈管理 ( 栈内复用模式 singleTask | 单实例模式 singleInstance )
【Android 应用开发】Activity 返回堆栈管理 ( 栈内复用模式 singleTask | 单实例模式 singleInstance )
26 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13886 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
25056 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18643 0
Java高新技术2--JAVA中枚举的各种应用以及单例模式
  在C/C++中枚举是一种构造数据类型 ,在java中枚举的实质是一个类  但是默认是没有构造方法的 但是我们可以为其添加构造方法 但是必须是私有的 .方法列表要在元素列表之下  。 其实在 Java类中定义枚举就是定义内部类   . 内部类和外部类 根据权限的不同 访问修饰符也不一样。
760 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
13817 0
351
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载