代码改变世界

单例模式

2017-08-01 20:10  grows  阅读(167)  评论(0编辑  收藏  举报

 

1.单例是什么?

就是类只能实例化一个对象,所有用到此对象的都是同一个对象

这就要求由类只能有一个实例,类本身去创建这个对象,其他类共用这个对象

 

2.创建对象两种方式:

1) new

2) 通过Class对象.newInstance()方法创建

3.打破上面两种创建的方式,通过把构造函数设置为private可以防止new创建对象,但是Java有反射机制,可以通过Class对象创建类,那么就要对Class.对象进行检查,保证其创建的是同一个对象。如何保证?通过Class对象的.newInstance()创建对象的时候,需要用到类的无参的构造函数,通过设置为private可以防止创建新的对象

 4,创建单例模式的条件

1) 私有化构造函数

2) 有类创建这个实例,

3) 并通过静态方法可以得到这个对象

5.创建单例模式的方式

  1)懒汉式(比较懒,所以在编译的时候不生成对象,在运行时生成对象)4

  线程不安全

package singletonmodel;
/**
 * 饿汉式但是没有考虑到线程安全
 * @author Administrator
 *
 */
public class Singleton_lh {
    /*
     * 私有化构造函数
     */
    private Singleton_lh(){
        
    }
    //创建静态变量
    private static Singleton_lh singleton=null;
    /*
     * 创建静态方法返回类的对象
     */
    public static Singleton_lh getInstance(){
        if(singleton==null)
        {
            singleton=new Singleton_lh();
            
        }
        return singleton;
    }
    

}

 

线程安全2

 

package singletonmodel;
/**
 * 线程安全的单利模式
 * @author Administrator
 *
 */
public  class SingletonLhSave {
    private static SingletonLhSave singletonLhSave=null;
    private SingletonLhSave(){
    }
    /*
     * 全局的线程安全,但是对于性能影响比较大
     */
    public synchronized  static SingletonLhSave getSingletonLhSave(){
        if(singletonLhSave==null)
        {
            singletonLhSave=new SingletonLhSave();
        }
        return singletonLhSave;
    }

}
package singletonmodel;
/**
 * 线程安全的单例模式,两次判断null
 * @author Administrator
 */
public  class SingletonLhSave2 {
    private static SingletonLhSave2 singletonLhSave2=null;
    private SingletonLhSave2(){
    }
    /*
     * 局部的线程安全,但是对于性能影响相对较少
     */
    public  static SingletonLhSave2 getSingletonLhSave(){
        if(singletonLhSave2==null)
        {//不会去锁定你的方法,而当singletonLhSave2为空时锁定类创建实例,即局部锁定
            synchronized(SingletonLhSave2.class){
                if(singletonLhSave2==null)
                {
                    singletonLhSave2=new SingletonLhSave2();
                }
            }
        }
        return singletonLhSave2;
    }
}

 

 

静态内部类

package singletonmodel;
/**
 * 线程安全的单例模式,静态内部类
 * @author Administrator
 */
public  class SingletonLhSave3 {
    
    private SingletonLhSave3(){
    }
    /*
     * 静态内部类,利用classload来保证初始化的时候只有一个线程,即线程安全,也没有性能消耗
     * 我怎么知道?大家都推荐使用,具体需要以后慢慢体会
     */
    private static class LanHan{
        private static SingletonLhSave3 singletonLhSave3=new SingletonLhSave3();
    }
    public  static SingletonLhSave3 getSingletonLhSave(){
        return LanHan.singletonLhSave3;
    }
}

 

 

1) 饿汉式(太饿了,所以在编译的时候就生成了对象,)1

 

package singletonmodel;
/**
 * 线程安全的单例模式,
 * @author Administrator
 */
public  class SingletonEh {
    private static SingletonEh singletonEh=new SingletonEh();
    private SingletonEh(){
    }
    /*
     *饿汉式,初始化的时候 已经创建了对象
     */
    public  static SingletonEh getSingletonLhSave(){
        return singletonEh;
    }
}

 

2) 登记式1

懒汉:调用方法时初始化进行加载(加载快,但是第一次调用时比较费时,之前不占用控件)

饿汉:类加载的时候就创建了对象(加载慢,第一次调用快,占空间)

那些场景需要用到单例模式,有什么优缺点

优缺点:

优点:只产生一个对象的实例

1.     节省空间,对于频繁创建和销毁的对象能供提交性能

2.     共享资源的统一

缺点:只产生一个单例

1.     不适合频繁变化的对象

2.     不能够抽象即不能够扩展

3.     职责过重

 

场景:

1.     频繁创建和销毁但是有经常使用的

2.     创建对象消耗资源比较多的

 

单例模式运用的实例:

Jdbc数据库连接池

任务管理器

日志

文件系统

打印机

心得:简单学习不是目的主要是能够掌握思想,能够应用