【Java基础】单例模式

单例模式

饿汉式单例模式

饿汉式即类被加载的时候就会生成单例实例。

//饿汉式
public class Singleton1 {
    private static  final  Singleton1 instance = new Singleton1();
    private Singleton1() {
        System.out.println("创建饿汉式单例成功");
    }
    public static Singleton1 getInstance(){
        return instance;
    }

    public static void  otherMethod(){
        System.out.println("执行其他方法");
    }
}

破坏

反射破坏
public static Object reflect(Class className) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    Constructor con = className.getDeclaredConstructor();
    con.setAccessible(true);
    return con.newInstance();
}

预防反射破坏单例;

private Singleton1() {
    if(instance!=null){
        throw new RuntimeException("单例对象不能重复创建");
    }
    System.out.println("创建饿汉式单例成功");
}
序列化破坏

要求serializable,新对象不走构造方法。

public static void serialAble(Object instance) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream bos=new ByteArrayOutputStream();
    ObjectOutputStream oos=new ObjectOutputStream(bos);
    oos.writeObject(instance);
    ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
    System.out.println(ois.readObject());
}

预防序列化破坏:

public Object readResolve(){
    return  instance;
}
unsafe破坏
public static void unsafe(Class<?> clazz){
    Object o=UnsafeUtils.getUnsafe().allocateInstance(clazz);
    System.out.println("创建实例成功");
}

不好避免

枚举类单例模式

public enum Singleton2 {
    MALE,FEMALE
}
public enum Singleton2 {
    instance;
    private Singleton2(){
        System.out.println("枚举饿汉式创建成功");
    }
    public static Singleton2 getInstance(){
        return instance;
    }
    public static void  otherMethod(){
        System.out.println("执行其他方法");
    }
    @Override
    public String toString() {
        return getClass().getName()+"@"+Integer.toHexString(hashCode());
    }
    public static void main(String[] args) {
        Singleton2.otherMethod();
        Singleton2 instance1 = Singleton2.getInstance();
        Singleton2 instance2 = Singleton2.getInstance();
        System.out.println(instance1);
        System.out.println(instance2);
    }

}

不好破坏,反射也不行。

懒汉式单例模式

在第一次使用的时候才会创建实例

package Singleton;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

public class Singleton3 {
    private static  Singleton3 instance = null ;
    private Singleton3() {
        if(instance!=null){
            throw new RuntimeException("单例对象不能重复创建");
        }
        System.out.println("创建饿汉式单例成功");
    }
    public static Singleton3 getInstance(){
        if(instance==null){
            instance=new Singleton3();
        }
        return instance;
    }

    public static void  otherMethod(){
        System.out.println("执行其他方法");
    }
    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
        //1 测试
        Singleton3.otherMethod();
        Singleton3 instance1 = Singleton3.getInstance();
        Singleton3 instance2=Singleton3.getInstance();
        System.out.println(instance1);
        System.out.println(instance2);

    }

}

在多线程情况下会出现线程安全问题。应用DCL懒汉式单例模式解决

DCL懒汉式单例模式

又称双检锁单例模式

public class Singleton4 {

    private Singleton4() {
        System.out.println("创建饿汉式单例成功");
    }
    //添加voilate关键字
   private voilate static  Singleton4 instance = null ;
   public static Singleton4  getInstance(){
   		//双重检查锁
        if(instance==null){
            synchronized (Singleton4.class){
                if(instance==null){
                    instance=new Singleton4();
                }
            }
        }
    return instance;
}

    public static void  otherMethod(){
        System.out.println("执行其他方法");
    }
    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
        //1 测试
        Singleton4.otherMethod();
        Singleton4 instance1 = Singleton4.getInstance();
        Singleton4 instance2=Singleton4.getInstance();
        System.out.println(instance1);
        System.out.println(instance2);

    }

}

内部类饿汉式

内部类在使用时初始化,是线程安全的。

public class Singleton5 {
    private Singleton5(){
        System.out.println("内部类饿汉式初始化");
    }
    public static class Holder{
        static Singleton5 instance =new Singleton5();
    }
    public static Singleton5 getInstance(){
        return Holder.instance;
    }
    public static void  otherMethod(){
        System.out.println("执行其他方法");
    }
}

在jdk中的体现

饿汉式

Runtime 饿汉式单例模式

private static Runtime currentRuntime = new Runtime();

懒汉式

System.console()

public static Console console() {
    if (cons == null) {
        synchronized (System.class) {
            cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
        }
    }
    return cons;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值