//饿汉式
public class Singledemo1 {
private static final Singledemo1 singledemo1=new Singledemo1();
public static Singledemo1 getInstance(){
return singledemo1;
}
private Singledemo1()
{
}
}
//特点:线程安全的 。在类加载时就创建对象,资源开销大 资源利用率低
//懒汉式
public class Singledemo2 {
private static Singledemo2 singledemo2=null;
private Singledemo2(){
if(singledemo2!=null)
{
throw new RuntimeException("错误");
}
public static synchronized Singledemo2 getInstance()
{
if(singledemo2==null)
{
singledemo2=new Singledemo2();
}
return singledemo2;
}
}
private Singledemo2 readResult()
{
return singledemo2;
}//防止反序列化时产生多个对象
}
//特点:延时加载,资源利用率高 但需要加锁 因为如果多个线程访问共享数据会造成并发问题效率低
//静态内部类单例模式
public class Singledemo3 {
private static class Singleton{
private static final Singledemo3 s=new Singledemo3();
}
public static Singledemo3 getInstance()
{
return Singleton.s;
}
private Singledemo3 (){
}
}
//步骤:1建立一个私有化的静态内部类 类中new一个单例对象
//2私有化构造方式
// 3通过静态方法返回实例
//特点:懒加载的,资源利用率高,不需要判断同步,效率高。
//注意:在加载外部类的时候内部类没有加载,只有调用getinstance方法后才加载内部类所以是懒加载的
// 为什么多次调用方法只返回一个对象?因为对象由final修饰 值只能赋值一次且是类变量类随着类的产生而产生
public enum Singledemo4 {
instance;
public void method()
{
}
}
//枚举类就是一个天然的单例模式,是由底层实现的。但不是懒加载 且预防了反射和反序列化的漏洞
//资源开销小,懒加载 静态内部类单例>懒汉式
//开销大,直接加载,枚举>饿汉式
注意:只有枚举类能够预防反序列化和反射的漏洞
反射时怎么防止漏洞的产生呢?
通过在构造方法中判断创建的单例实例是否存在,若存在抛出Runtime异常
反序列化怎么防止漏洞的产生呢?
通过在对象所属类中写readResovle方法返回实例对象即可