一、饿汉式--无法给单例对象的构造方法传递参数,且线程不安全
/**
* Created by serenitynanian on 2018/3/13.
* 饿汉式--无法向单例对象的构造方法传递参数 线程不安全
*/
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return instance;
}
}
二、懒汉式--可以给构造函数传递参数,但线程不安全
/**
* Created by serenitynanian on 2018/3/13.
* 懒汉式-- 可以给构造函数传递参数 线程不安全
*/
public class LazySingleton {
private static LazySingleton lazySingleton ;
private LazySingleton(){}
public static LazySingleton getInstance(){
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton ;
}
}
三、双重检查--可以给构造函数传递参数,且线层安全
/**
* Created by serenitynanian on 2018/3/13.
* 双重检查--- 线程安全需要时可以使用此方法创建单例 线程安全
* volatile关键字的两层含义
* 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
* 1.保证了不同线程对这个变量进行操作的可见性,既一个线程修改了某个变量,这个变量的新值对其他线程是立即可见的;
* 2.禁止进行指令重排序;生成的机器指令与字节码指令顺序不一致;
*/
public class DoubleCheckSingleton {
//volatile
//线程并发时,当变量被改动了,所有的线程都能及时的访问到最新的数据
//会屏蔽掉虚拟机的一些优化代码
private volatile static DoubleCheckSingleton doubleCheckSingleton ;
private DoubleCheckSingleton(){}
public static DoubleCheckSingleton getInstance() {
if (null == doubleCheckSingleton) {
synchronized (DoubleCheckSingleton.class) {
if (null == doubleCheckSingleton) {
doubleCheckSingleton = new DoubleCheckSingleton();
}
}
}
return doubleCheckSingleton ;
}
}
四、静态被内部类--不能给构造函数传递参数,但线程安全
/**
* Created by serenitynanian on 2018/3/13.
* 静态内部类创建单例---无法给构造函数传递参数,线程安全
*/
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton(){}
private static class SingletonHolder{
//注意:静态内部类的静态属性实例化时,是由JVM保证线程的安全---虚拟机的机制
private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
}
//只有调用了getInstance方法之后,才会实例化StaticInnerClassSingleton
public static StaticInnerClassSingleton getInstance(){
return SingletonHolder.instance ;
}
}
五、使用枚举创建单例
/**
* Created by serenitynanian on 2018/3/13.
* 枚举的方式创建单例
* java设计者建议使用的最优方法,参数和安全都可以自己控制;--《Effective Java》 java高效编程
*/
public enum EnumSingleton {
instance(1,"参数");
private int index ;
private String params ;
//参数可控的
EnumSingleton(int index, String params) {
this.index = index ;
this.params = params ;
}
public void operate(){
System.out.println("------operate------");
}
}
网友评论