java单例模式的实现方式
程序员文章站
2022-06-03 15:13:45
...
单例模式的六种实现方式,代码注释比较详细,不多说,请看详细代码
一、饿汉模式/立即加载模式
/**
* Created by Xiao GuoJian on 2018/1/25.
* 立即加载/饿汉模式
* 此模式是在类被加载的时候对象已经被创建,不管有没有使用,都创建了
* 此模式是线程安全的
*/
public class Singleton1 {
private static Singleton1 singleton = new Singleton1();
private Singleton1(){}
public static Singleton1 getInstance(){
return singleton;
}
}
二、懒汉模式/延迟加载模式
/**
* Created by Xiao GuoJian on 2018/1/25.
* 延迟加载/懒汉模式
* 此模式是在调用getInstance()方法的时候实例才会被创建
* 此模式是非线程安全的
*/
public class Singleton2 {
private static Singleton2 singleton;
//私有化构造器
private Singleton2(){}
public static Singleton2 getInstance(){
if(singleton == null){
singleton = new Singleton2();
}
return singleton;
}
}
懒汉模式的优化,使用双检查锁机制,可以满足线程安全和高性能
/**
* Created by Xiao GuoJian on 2018/1/25.
* 延迟加载/懒汉模式
* 此模式是在调用getInstance()方法的时候实例才会被创建
* 如果单独使用synchronized关键字,则会影响效率
* 所以这里使用DCL(Double Check Locking)双检查锁机制,既保证了线程安全,又保证了效率
*
*/
public class Singleton2a {
/*
这里在声明变量时使用了volatile关键字来保证其线程间的可见性;
在同步代码块中使用二次检查,以保证其不被重复实例化。
集合其二者,这种实现方式既保证了其高效性,也保证了其线程安全性。
*/
private volatile static Singleton2a singleton2a;
//私有化构造器
private Singleton2a(){}
public static Singleton2a getInstance(){
if(singleton2a == null){
synchronized (Singleton2a.class){
if(singleton2a == null){
singleton2a = new Singleton2a();
}
}
}
return singleton2a;
}
}
三、静态内置类模式
package com.shone.thread.singleton;
/**
* Created by Xiao GuoJian on 2018/1/25.
* 使用静态内置类实现单例模式
* 此模式是线程安全的
*/
public class Singleton3 {
//内部类
private static class InnerSingleton{
private static Singleton3 singleton = new Singleton3();
}
private Singleton3(){}
public static Singleton3 getInstance(){
return InnerSingleton.singleton;
}
}
四、序列化与反序列化模式(其实应该叫静态内置类模式的序列化问题优化)
package com.shone.thread.singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* Created by Xiao GuoJian on 2018/1/25.
* 序列化和反序列化的单例模式
* 静态内置类可以达到线程安全问题,但是如果遇到需要序列化和反序列化对象是,则会出现问题
* 序列化对象的hashCode和反序列化后得到对象的hashCode的值不一样,单例被破坏了
*
* 在中定义一个readResolve()方法,反序列化的时候会去调用这个方法
*/
public class Singleton4 implements Serializable{
private final static long serivalVersionUID=888L;
private static class InnerSington{
private static Singleton4 singleton = new Singleton4();
}
private Singleton4(){}
public static Singleton4 getInstance(){
return InnerSington.singleton;
}
//该方法在反序列化时会被调用,该方法不是接口定义的方法
//反序列化的实例和序列化的实例是同一个实例
protected Object readResolve() throws ObjectStreamException {
return InnerSington.singleton;
}
}
五、静态代码块模式
package com.shone.thread.singleton;
/**
* Created by Xiao GuoJian on 2018/1/25.
* 使用静态代码块实现单例模式
*
* 静态代码块在类加载的时候执行,并且只执行一次
*/
public class Singleton5 {
private static Singleton5 singleton;
static {
singleton = new Singleton5();
}
private Singleton5(){}
private static Singleton5 getInstance(){
return singleton;
}
}
六、枚举模式
package com.shone.thread.singleton;
/**
* Created by Xiao GuoJian on 2018/1/25.
*
* 使用枚举实现单例模式
*
* 利用的是枚举的构造方法在类加载的时候被调用的特性,跟静态代码块比较类似
* 使用方式:SingletonEnum.singletonFactory.getInstance();
*/
public enum SingletonEnum {
singletonFactory;
private Singleton6 singleton;
//枚举的构造方法是在类加载的时候执行的
private SingletonEnum(){
singleton = new Singleton6();
}
public Singleton6 getInstance(){
return singleton;
}
}
//需要实现单例的类
class Singleton6{
public Singleton6(){}
}
枚举模式的优化
package com.shone.thread.singleton;
/**
* Created by Xiao GuoJian on 2018/1/25.
*
* 完善使用枚举实现单例模式
* 枚举实现单例默认,暴露了实现细节
* 此代码则是将实现方式隐藏起来,直接调用即可
*/
public class SingletonFactory {
private enum SingletonEnum {
singletonFactory;
private Singleton7 singleton;
//枚举的构造方法是在类加载的时候执行的
private SingletonEnum(){
singleton = new Singleton7();
}
public Singleton7 getInstance(){
return singleton;
}
}
public static Singleton7 getInstance(){
return SingletonEnum.singletonFactory.getInstance();
}
}
//需要实现单例的类
class Singleton7{
public Singleton7(){}
}
上一篇: 抖音被限流怎么办 抖音被限流可以恢复吗
下一篇: unity实现简单贪吃蛇游戏