防止单例模式被攻击的一个Demo

我们要创建的单例的类如下:

package DesignMode;

public class SingletonMode
{
    private static volatile SingletonMode single = null;

    private static boolean flag = true;

    private SingletonMode()
    {
        synchronized(SingletonMode.class)
        {
            if(flag)
            {
                flag = false;
            }else
            {
                throw new RuntimeException("单例模式被攻击!!!");
            }
        }
    }

    public static SingletonMode getInstance()
    {
        if (single == null)
        {
            // 锁的范围缩小
            synchronized (SingletonMode.class)
            {
                if (single == null)
                {
                    single = new SingletonMode();
                }
            }

        }
        return single;
    }
}

我们的攻击类如下:

package DesignMode;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class attackSingleton
{
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        Class<?> classType = SingletonMode.class;

        Constructor<?> c = classType.getDeclaredConstructor(null);
        c.setAccessible(true);

        SingletonMode m = (SingletonMode)c.newInstance();
        System.out.println(m.hashCode());
        System.out.println("m: "+m.getClass());

        SingletonMode n = SingletonMode.getInstance();

        System.out.println(m == n);


        System.out.println(n.hashCode());
        System.out.println("n: "+n.getClass());
    }

}

运行结果如下:

118352462
m: class DesignMode.SingletonMode
Exception in thread "main" java.lang.RuntimeException: 单例模式被攻击!!!
    at DesignMode.SingletonMode.<init>(SingletonMode.java:18)
    at DesignMode.SingletonMode.getInstance(SingletonMode.java:32)
    at DesignMode.attackSingleton.main(attackSingleton.java:19)

不过上面这个Demo只是防止被攻击,如果一个线程通过反射创造出一个实例对象之后,其他线程就无法通过getInstance()方法得到这个实例对象了。因此我们不能再用懒汉式单例创建,而应该改用饿汉式。

//饿汉式单例类.在类初始化时,已经自行实例化 
public class Singleton1 {
    private Singleton1() {}
    private static final Singleton1 single = new Singleton1();
    //静态工厂方法 
    public static Singleton1 getInstance() {
        return single;
    }
}

另外大家可以参考:

如何防止单例模式被攻击

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值