单例模式

单例模式

package singleton.type1;
/*所谓单例设计模式,就是采取一定的方法在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得该对象实例的方法
* */
public class SingleTest01 {
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance==instance1);
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());

    }
}
/*优缺点分析
* 优点:写法比较简单,就是在类装载的时候就完成了实例化。避免了线程同步问题
* 缺点:在类装载的时候完成了实例化,没有达到LZAY LOADING的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费
* */



/*饿汉式(静态变量)*/
class Singleton{
//    1.构造器私有化,外部不能new
    private Singleton(){

    }
//    2.本类内部创建一个成员变量,用它来实例对象
    private final static Singleton instance=new Singleton();
//    3.提供一个共有的静态方法得到实例对象
    public static Singleton getInstance(){
        return instance;
    }

}
package singleton.type2;
/*所谓单例设计模式,就是采取一定的方法在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得该对象实例的方法
* */
public class SingleTest02 {
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }
}
/*优缺点分析
和上面的静态变量一模一样
* 优点:写法比较简单,就是在类装载的时候就完成了实例化。避免了线程同步问题
* 缺点:在类装载的时候完成了实例化,没有达到LZAY LOADING的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费
* */


/*饿汉式(静态代码块)*/
class Singleton{
//    1.构造器私有化,外部不能new
    private Singleton(){

    }
//    2.本类内部创建一个成员变量,用它来实例对象
    private static Singleton instance;
//在静态代码块中。创建单例对象
    static {
//        这里直接instance代表上面的instance,否则空指针
        instance=new Singleton();
    }

//    3.提供一个共有的静态方法得到实例对象
    public static Singleton getInstance(){
        return instance;
    }

}
package singleton.type3;

public class SingleTest03 {
    public static void main(String[] args) {
        /*饿汉式*/
        singleton.type3.Singleton instance = singleton.type3.Singleton.getInstance();
        singleton.type3.Singleton instance2 = singleton.type3.Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }

}
/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/
/*优缺点
 优点:起到了懒加载的效果,但只能在单线程下使用
 缺点:在多线程下,会产生多个实例
 不推荐使用
* */
class Singleton{
    private Singleton(){

    }
    private static Singleton instance;

    public static Singleton getInstance(){
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}
package singleton.type4;

public class SingleTest04 {
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }

}

/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/

/*针对前面一种给出常识的改进*/
/*优缺点
 优点:解决了线程不安全问题
 缺点:效率太低了,只执行一次实例化代码就可以了,不需要每次进行同步,下一次就直接返回对象实例就可以了
 不推荐使用
* */
class Singleton{
    private Singleton(){

    }
    private static Singleton instance;

    public static synchronized Singleton getInstance(){
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题*/
package singleton.type5;

public class SingleTest05{
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }

}

/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/

/*针对前面一种给出常识的改进*/
/*这种同步不同实现线程同步的作用,会产生多个实例*/
/*优缺点
 优点:解决了线程不安全问题
 缺点:效率太低了,只执行一次实例化代码就可以了,不需要每次进行同步,下一次就直接返回对象实例就可以了
 不能使用
* */
class Singleton{
    private Singleton(){

    }
    private static Singleton instance;

    public static Singleton getInstance(){
        if(instance==null){
            synchronized(Singleton.class) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题
* 前者效率低 后面线程不安全*/
package singleton.type6;

public class SingleTest06 {
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }

}

/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/

/*针对前面一种给出常识的改进*/
/*双重检查
推荐使用 确保线程安全 延时加载 效率高
* */
class Singleton{
    private Singleton(){

    }
    /*volatile的作用*/
    private static volatile Singleton instance;

    public static synchronized Singleton getInstance(){
        if(instance==null){
            synchronized (Singleton.class){
                if(instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}
/*加在方法上 以及 加在判断语句里面 syschronized 都没有解决这个问题*/
package singleton.type7;

public class SingleTest07 {
    public static void main(String[] args) {
        /*饿汉式*/
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance==instance2);
        System.out.println(instance.hashCode());
        System.out.println(instance2.hashCode());

    }

}

/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/

/*针对前面一种给出常识的改进*/
/*静态内部类  外部类被装载,内部类还没被装载   在调用方法时内部类会被装载而且装载一次,线程安全的
推荐使用 确保线程安全 延时加载 效率高
* */
class Singleton{
    private Singleton(){
/*jvm在装载类的时候是线程安全的,利用了这个特性*/
    }
    private static volatile Singleton instance;

    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }
    /*提供一个静态的共有方法*/
    public static synchronized Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }


}
package singleton.type8;

import org.w3c.dom.ls.LSOutput;

public class SingleTest08 {
    public static void main(String[] args) {
        //饿汉式
        Singleton instance = Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance==instance1);
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());
        instance.sayOK();
    }

}

/*懒汉式*/
/*提供一个静态的共有方法。当使用到该方法时,才去创建instance*/

/*针对前面一种给出常识的改进*/
/*枚举.推荐使用,不仅能避免多线程同步问题,还可以防止反序列化重新创建新的对象
* */
enum Singleton{
    INSTANCE;
    public void sayOK(){
        System.out.println("ok");
    }
}
/*推荐饿汉式 枚举 静态内部类 懒汉式双重检查 一共5种方式
* 饿汉式你能确保一定使用*/
/*java.lang.Runtime就是经典的单例模式*/
/*单例模式保证了系统内存中该类只存在一个对象,节省了系统空间,对于一些需要频繁创建和销毁的对象,
使用单例模式可以提高系统性能

想实例化一个单例类的对象时,必须记住使用相应的获取该对象的方法,而不是使用new

单例模式使用的场景:需要频发的创建和销毁对象,但又要经常使用的对象。工具类对象,频繁使用数据库或者文件
的对象,比如数据源 session工厂等*/

自己被加载时就将自己实例化,称为饿汉式单例类
第一次被引用时,才会将自己实例化,称为懒汉式单例类

全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务