1.饿汉模式
image.png示例代码:
public class EagerLoadBalancer {
private static final EagerLoadBalancer instance = new EagerLoadBalancer();
private EagerLoadBalancer() {
}
public static EagerLoadBalancer getInstance(){
return instance;
}
}
2.懒汉模式(双重检查锁定模式)
image.png示例代码:
public class LazyLoadBalancer {
private volatile static LazyLoadBalancer instance = null;
private LazyLoadBalancer() {
}
public static LazyLoadBalancer getInstance(){
if (instance==null) {
synchronized (LazyLoadBalancer.class) {
if (instance==null) {
instance = new LazyLoadBalancer();
}
}
}
return instance;
}
/*这样不支持多线程。
public static LazyLoadBalancer getInstance() {
if (instance == null) {
instance = new LazyLoadBalancer();
}
return instance;
} */
/*这样虽然解决了线程安全问题,
但是每次调用getInstance()时都需要进行线程锁定判断,
在多线程高并发访问环境中,将会导致系统性能大大降低。
synchronized public static LazyLoadBalancer getInstance() {
if (instance == null) {
instance = new LazyLoadBalancer();
}
return instance;
} */
}
3.Initialization Demand Holder (IoDH)
示例代码:
public class IoDHLoadBalancer {
private IoDHLoadBalancer() {
System.out.println("ss");
}
private static class HolderClass {
private static final IoDHLoadBalancer instance = new IoDHLoadBalancer();
}
public static IoDHLoadBalancer getInstance(){
return HolderClass.instance;
}
public static void main(String[] args) {
System.out.println(IoDHLoadBalancer.getInstance()==IoDHLoadBalancer.getInstance());
}
}
4.拓展练习
示例代码:
public class ExpandLoadBalancer {
private volatile static List<ExpandLoadBalancer> instances = new ArrayList<>();
private static final int MAX_INSTANCE = 3;
private ExpandLoadBalancer() {
}
public static ExpandLoadBalancer getInstance(){
if (instances.size()<MAX_INSTANCE) {
synchronized (ExpandLoadBalancer.class) {
if (instances.size()<MAX_INSTANCE) {
instances.add(new ExpandLoadBalancer());
}
}
}
return instances.get(new Random().nextInt(instances.size()));
}
public static void main(String[] args) {
System.out.println(ExpandLoadBalancer.getInstance());
System.out.println(ExpandLoadBalancer.getInstance());
System.out.println(ExpandLoadBalancer.getInstance());
System.out.println(ExpandLoadBalancer.getInstance());
System.out.println(ExpandLoadBalancer.instances);
}
}
5.问题
以上方法存在反射攻击或者反序列化攻击的可能。
最终解决方法:枚举单例
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("doSomething");
}
}
public class Main {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
网友评论