单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点
饿汉模式
不能惰性初始化,在JVM一开始就会被初始化,
public class HungrySingleton {
//类加载时就初始化
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
System.out.println("HungrySingleton is created");
}
public void run() {
System.out.println("HungrySingleton is running");
}
public static HungrySingleton getInstance() {
return instance;
}
public static void main(String[] args) {
System.out.println("start");
HungrySingleton.getInstance().run();
}
}
懒汉模式
双重锁检查,避免在多线程情况下创建多个实例,但是如果单例类实现了java.io.Serializable
接口,可能被反序列化,从而产生新的实例。
public class LazySingletonOne {
private volatile static LazySingletonOne instance;
private LazySingletonOne() {
System.out.println(("LazySingletonOne is created"));
}
public void run() {
System.out.println(("LazySingletonOne is running"));
}
public static LazySingletonOne getInstance() {
if (instance == null) {
synchronized (LazySingletonOne.class) {
if (instance == null) {
instance = new LazySingletonOne();
}
}
}
return instance;
}
public static void main(String[] args) {
System.out.println("start");
LazySingletonOne.getInstance().run();
}
}
静态内部类
将单例类设置为final
类型,能够禁止克隆的发生,同样静态内部类只有在第一次被引用时才加载,
public final class StaticNestedSingleton {
// 声明为 final 能防止其在派生类中被 clone
private StaticNestedSingleton() {
System.out.println(("StaticNestedSingleton is created"));
}
public static StaticNestedSingleton getInstance() {
return NestedClass.instance;
}
public void run() {
System.out.println("run");
}
//在第一次被引用时被加载
static class NestedClass {
private static StaticNestedSingleton instance = new StaticNestedSingleton();
}
public static void main(String[] args) {
System.out.println("start");
StaticNestedSingleton.getInstance().run();
}
}
枚举类模式
enum
方法反序列化重新创建新的对象- 类的修饰
abstract
,所以没有办法实例化,反射也不行 - 关于线程安全,是通过类加载机制来保证的,
INSTANCE
实例化的时机是在static
块中,JVM加载类的过程是线程安全的。
public enum EnumSingleton {
INSTANCE;
private final String[] preference = {"intresting", "nice", "just so so"};
public void printPreference() {
System.out.println(Arrays.toString(preference));
}
}
Java反编译查看
Compiled from "EnumSingleton.java"
public final class com.scxx.blackpanther.EnumSingleton extends java.lang.Enum<com.scxx.blackpanther.EnumSingleton> {
public static final com.scxx.blackpanther.EnumSingleton INSTANCE;
public static com.scxx.blackpanther.EnumSingleton[] values();
public static com.scxx.blackpanther.EnumSingleton valueOf(java.lang.String);
public void printPreference();
static {};
}
scala实现单例模式
object
在scala中被称作[单例对象]
object关键字创建了一个新的单例类型,就像一个class只有一个被命名的实例,如果你熟悉java,在scala中声明一个object就像创建了一个匿名类的实例。
object Singleton2Scala {
def sum(l: List[Int]): Int = l.sum
}