java单例模式如何才能保证线程安全呢?下面要给大家分享的就是线程安全的单例模式代码,一起来详细的了解一下。
1.饿汉式单例,指的就是在方法调用之前,实例就已经创建完成了。
package jichu; public class Singleton { private static Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
注意一下,要保证系统当中不会有人创建多余的实例,所以,就将构造函数设置成为了private,instance对象必须是private并且要是static的,假如不是private的话,那么,instance的安全性将不能够保证,一个很小的意外,很有可能会导致instance变为null。
存在的问题,Singleton实例是在什么时候创建是不收控制的,对于静态成员instance,它会在类第一次初始化时被创建,那么这个时候,并不一定是getInstance方法第一次被调用的时候。
2、加入synchronized的懒汉式单例,指在调用时才会去创建这个实例,为了防止对象被多次创建,使用synchronized进行方法同步。
package jichu; public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这样充分的利用了延迟加载,只有在真正要创建的时候创建对象,但是,并发环境下加锁,竞争激烈的场合对性能会造成一定的影响。
3、使用静态内部类方式,利用classloder机制来保证初始化instance时只有一个线程。
和饿汉式区别:饿汉式只要Singleton类被加载,instance就会被实例化,这种方式是Singleton类被加载了,instance也不一定被初始化,只有通过调用getInstance()方法的时候,才会显式装载SingletonHolder类,从而实例化instance,能够做到真正需要的时候创建实例。
package jichu; public class Singleton { private Singleton() {} // 静态内部类 private static class SingletonHolder { private static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }
4.双重校验锁(不大推荐)。用两个if判断这个对象是否是空的原因,主要是在于,多个线程同时创建对象时,多个线程有可能都停止在第一个if判断的地方,等待锁的释放,然后多个线程都创建了对象,这样就不是单例模式了,所以的话,使用两个if。
package jichu; public class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
5.使用static代码块,静态代码块中的代码在使用类的时候就已经执行。
package jichu; public class Singleton { private static Singleton instance = null; private Singleton() {} static { instance = new Singleton(); } public static Singleton getInstance() { return instance; } }
6.使用枚举数据类型。
package jichu; public class Singleton { private enum MyEnumSingleton { singletonFactory; private Singleton instance; // 枚举类的构造方法在类加载时被实例化 private MyEnumSingleton() { instance = new Singleton(); } public Singleton getInstance() { return instance; } } public static Singleton getInstance() { return MyEnumSingleton.singletonFactory.getInstance(); } }
以上的内容就为你介绍到这里了,请继续关注奇Q工具网吧,更多java编程常见问题,可以为你进行分享哦。