1. 什么是单例模式
一个类只有一个实例,并提供一个全局访问的入口
2. 为什么要用单例
- 只生成一个实例,减少了系统资源的开销
- 提供了统一的访问入口,对共享资源的访问较为便利
3. 具体实现
1) 饿汉式 -静态常量、静态方法
public class SingletonTest {
private final static SingletonTest INSTANCE = new SingletonTest();
private SingletonTest(){}
public static SingletonTest getInstance(){
return INSTANCE;
}
}
这种写法比较简单,在类装载的时候就进行初始化,不会有线程并发的问题,但就是没有起到延迟加载的效果,当然也可以用静态代码块的方式:
public class SingletonTest {
private final static SingletonTest INSTANCE;
static {
INSTANCE = new SingletonTest();
}
private SingletonTest(){}
public static SingletonTest getInstance(){
return INSTANCE;
}
}
2) 懒汉式,线程不安全
public class SingletonTest {
private static SingletonTest instance;
private SingletonTest(){}
public static SingletonTest getInstance(){
if(instance==null){
instance = new SingletonTest();
}
return instance;
}
}
有延迟加载的效果,但多线程下会有并发的问题
3)懒汉式 -线程安全,效率太低
public class SingletonTest {
private static SingletonTest instance;
private SingletonTest(){}
public static synchronized SingletonTest getInstance(){
if(instance==null){
instance = new SingletonTest();
}
return instance;
}
}
下面是同步代码块的方式,但其实也是线程不安全的,也不推荐使用
public class SingletonTest {
private static SingletonTest instance;
private SingletonTest(){}
public static SingletonTest getInstance(){
if(instance==null){
synchronized(SingletonTest.class){
instance = new SingletonTest();
}
}
return instance;
}
}
4) 双重检查,推荐使用
public class SingletonTest {
private static SingletonTest instance;
private SingletonTest(){}
public static SingletonTest getInstance(){
if(instance==null){
synchronized(SingletonTest.class){
if(instance==null){
instance = new SingletonTest();
}
}
}
return instance;
}
}
线程安全,也是延迟加载,效率较高
5) 嵌套类
public class SingletonTest {
private SingletonTest instance;
private static class SingletonInstance {
private static final SingletonTest INSTANCE = new SingletonTest();
}
public static SingletonTest getInstance(){
return SingletonInstance.INSTANCE;
}
}
线程安全,延迟加载,效率高
5) 枚举类
public enum SingletonTest {
INSTANCE;
public void otherMethod(){
}
}