一、基本要求:
-
类构造器私有
-
持有自己类型的属性
-
对外提供获取实例的静态方法
二、饿汉模式
package singleton;
public class HungrySingleton {
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){
}
public static HungrySingleton getHungrySingleton() {
return hungrySingleton;
}
}
在类加载时new对象,由于类只会加载一次,因此饿汉模式天生线程安全。
三、懒汉模式
package singleton;
public class LazySingleton {
private static volatile LazySingleton lazySingleton = null;
private LazySingleton(){
}
public static LazySingleton getInstance(){
//1.
if(lazySingleton == null){
//2.
synchronized(LazySingleton.class){
//3.
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
1.synchronized代码块代替synchronized方法,使锁的范围更小;
2.为什么在3处加null判断,因为多线程同时走到2处,会创建多个对象;
3.为什么在1处加null判断,因为可以减少进入synchronized代码块的机会,提高效率。
四、内部类实现
package singleton;
public class LazySingletonInnerClass {
private static LazySingletonInnerClass lazySingletonInnerClass = null;
private LazySingletonInnerClass(){
if(lazySingletonInnerClass != null){
throw new RuntimeException("不允许创建多个实例");
}
}
public static LazySingletonInnerClass getLazySingletonInnerClass() {
return LazyHolder.LAZY;
}
private static class LazyHolder{
private static final LazySingletonInnerClass LAZY = new LazySingletonInnerClass();
}
}
利用了静态内部类只初始化一次的特性保证单例。
五、枚举实现
package singleton;
public enum RegistEnumSingleton {
INSTANCE;
public static RegistEnumSingleton getInstance(){
return INSTANCE;
}
}
六、注册容器式单例
package singleton;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class RegistContainerSingleton {
private RegistContainerSingleton(){
}
private static Map<String, Object> ioc = new ConcurrentHashMap<String, Object>();
public Object getBean(String className){
synchronized(ioc) {
if (!ioc.containsKey(className)) {
Object object = null;
try {
object = Class.forName(className);
ioc.put(className, object);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
return ioc.get(className);
}
}
}