关于Java单例

参考资料:http://blog.csdn.net/haoel/article/details/4028232

public class SingletonTest implements Runnable {
    static SingletonClass1 instance = null;

    public static void main(String args[]) {
        // SingletonClass0 instance = new SingletonClass0();// The constructor
        // SingletonClass0() is not visible

        for (int i = 0; i < 15; i++) {
            new Thread(new SingletonTest()).start();
        }
        // System.out.println(instance.getClass());

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        SingletonClass6.getInstance();
        // System.out.println(SingletonClass7.instance.hashCode());
    }
}

class SingletonClass0 {
    private static SingletonClass0 instance = null;

    private SingletonClass0() {
        System.out.println("constructor run");
    }

    public static SingletonClass0 getInstance() {// wrong 单线才单线程下没问题,多线程下仍会有多个实例
        if (instance == null) {
            instance = new SingletonClass0();
            System.out.println(instance.hashCode());
        }
        return instance;
    }
}

class SingletonClass1 {
    private static SingletonClass1 instance = null;

    private SingletonClass1() {
        System.out.println("constructor run");
    }

    public static SingletonClass1 getInstance() {// wrong 多线程下仍会有多个实例,与上一种
                                                    // 区别在于过个线程的new过程被同步了
        if (instance == null) {
            synchronized (SingletonClass1.class) {
                instance = new SingletonClass1();
                System.out.println(instance.hashCode());
            }
        }
        return instance;
    }
}

class SingletonClass2 {
    private static SingletonClass2 instance = null;

    private SingletonClass2() {
        System.out.println("constructor run");
    }

    public static SingletonClass2 getInstance() {
        synchronized (SingletonClass2.class) {// right。只会有一个线程new实例,但阻碍了后续线程读实例
            if (instance == null) {
                instance = new SingletonClass2();
                System.out.println(instance.hashCode());
            }
        }
        return instance;
    }
}

class SingletonClass3 {
    private static SingletonClass3 instance = null;

    private SingletonClass3() {
        System.out.println("constructor run");
    }

    public static SingletonClass3 getInstance() {
        synchronized (SingletonClass3.class) {// right
                                                // 只会有一个线程new实例,不会影响后续线程读实例,但instance=new
                                                // SingletonClass3()在JVM内不是原子操作,内部的几个步骤可能乱序,从而出错
            if (instance == null) {
                synchronized (SingletonClass1.class) {
                    if (instance == null) {
                        instance = new SingletonClass3();
                        System.out.println(instance.hashCode());
                    }
                }
            }
        }
        return instance;
    }
}

class SingletonClass4 {
    private static volatile SingletonClass4 instance = null;// right
                                                            // 只有一个实例,volatite保证了在JVM内部new
                                                            // instance的几个操作禁止指令重排序优化

    private SingletonClass4() {
        System.out.println("constructor run");
    }

    public static SingletonClass4 getInstance() {
        synchronized (SingletonClass4.class) {
            if (instance == null) {
                synchronized (SingletonClass1.class) {
                    if (instance == null) {
                        instance = new SingletonClass4();
                        System.out.println(instance.hashCode());
                    }
                }
            }
        }
        return instance;
    }
}

class SingletonClass5 {// right,但是由类加载器在类加载时创建实例,我们无法控制实例创建的时机以干一些事(比如某个配置文件,或是某个被其它类创建的资源)
    public volatile static SingletonClass5 instance = new SingletonClass5();

    private SingletonClass5() {
        System.out.println("constructor run");
    };

    public static SingletonClass5 getInstance() {
        System.out.println(instance.hashCode());
        return instance;
    }
}

class SingletonClass6 {// 仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了
                        // getInstance()
                        // 之外没有办法访问它,因此它只有在getInstance()被调用时才会真正创建;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖
                        // JDK 版本
    private static class SingletonHolder {
        private static final SingletonClass6 INSTANCE = new SingletonClass6();
    }

    private SingletonClass6() {
        System.out.println("constructor run");
    }

    public static final SingletonClass6 getInstance() {
        System.out.println(SingletonHolder.INSTANCE.hashCode());
        return SingletonHolder.INSTANCE;
    }
}

class SingletonClass7 {
    public SingletonClass7() {
        System.out.println("constructor run");
    }
}

enum SingletonClass {
    instance;
}

时间: 2024-08-05 12:38:07

关于Java单例的相关文章

java单例类/

java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一但有了初始值,就不能被重新赋值 static修饰的成员变量可以在静态代码块中 或申明该成员时指定初始值 实例成员可以在非静态代码块中,申明属性,或构造器中指定初始值 final修饰的变量必须要显示初始化 final修饰引用变量不能被重新赋值但是可以改变引用对象的内容分(只要地址值不变) final修

Java 单例

最近在网上看到一篇关于 Java 单例的创建问题,虽然是一个 Java 程序员,但是到现在还没有真正的深入了解到 Java 的原理和机制.所以每每看到这样能够"真正"接触 Java 的机会内心总是充满了欣喜.记录下,以后备用. 懒汉模式 public class Singlton{ private static Singleton instance; private Singlton(){} public static Singlton getInstance(){ if(instac

java单例-积木系列

一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒汉,因为它是属于延迟加载这个实例的,也就是说不用到的时候,不实例化对象的. public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInst

Java单例的实现

1.声明实例变量(静态) 2.私有化构造函数 3.创建获取实例的方法 public class Singleton{ //创建实例变量 private static Singleton singleton; //私有化构造函数 private Singleton(){ } //创建获取实例的方法 public static Singleton getInstance(){ if(singleton==null){ singleton=new Singleton(); } return singl

Java单例设计模式的实现

1. 单例设计模式的定义 单例设计模式确保类只有一个实例对象,类本身负责创建自己的对象并向整个系统提供这个实例.在访问这个对象的时候,访问者可以直接获取到这个唯一对象而不必由访问者进行实例化. 单例设计模式保证了全局对象的唯一性,在许多场景中都有应用.例如Windows中多个进程或线程同时操作一个文件的时候,所有的进程或线程对于同一个文件的处理必须通过唯一的实例来进行. 2. java单例设计模式的几种实现方式 单例设计的最大特点是类的构造函数是私有的,确保了只能由类本身创建对象,而访问者无法进

Java——单例设计模式

设计模式:解决某一类问题最行之有效的方法.Java中23种设计模式:单例设计模式:解决一个类在内存中只存在一个对象. 想要保证对象唯一.1,为了避免其他程序过多建立该类对象.先禁止其他程序建立该类对象2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象.3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式 这三部怎么用代码体现呢?1,将构造函数私有化.2,在类中创建一个本类对象.3,提供一个方法可以获取到该类对象. 对于事物该怎么描述,还怎么描述.当需要将该事物的对象

Java 单例总结

1:懒汉式,不保证线程安全 package com.yan.singleton; public class LazySingleton { private static final LazySingleton instance = null; private LazySingleton(){} public static LazySingleton getLazySingleton(){ if(null==instance){ return new LazySingleton(); } retu

Java: 单例设计模式

设计模式: * 设计模式:解决某一类问题最行之有效的方法:* Java有23中设计模式* 单例设计模式:解决一个类在内存只存在一个对象:* * 想要保证对象唯一* 1.为了避免其他程序过多建立该类对象.先控制禁止其他程序建立该类对象* 2.还为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象* 3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式* * 这三部如何用代码体现呢?* 1. 将构造函数私有化* 2. 在类中建立一个本类对象* 3. 提供一个方法可以获取到该对象

从一个简单的Java单例示例谈谈并发

一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static UnsafeLazyInitiallization instance; private UnsafeLazyInitiallization() { } public static UnsafeLazyInitiallization getInstance(){ if(instance==null){ /

从一个简单的Java单例示例谈谈并发 JMM JUC

原文: http://www.open-open.com/lib/view/open1462871898428.html 一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static UnsafeLazyInitiallization instance; private UnsafeLazyInitiallization() { } public static U