单例模式

介绍

单例模式:采用特定的方法导致某个类,只有一个对象实例,并且该类只提供一个取得其对象实例的方法。
创建单例模式:总共有八种创建单例模式的方法。
单例模式保证了系统中只有一个对象,对于需要频繁创建和销毁的对象。使用单例模式可以提高系统性能。
单例模式创建的方法是对象名加姓名。而不是通过new。
使用场景:频繁创建和销毁的对象。比如:工具类对象,频繁访问数据库的文件对象

饿汉式(静态常量)

  1. 构造器私有化
  2. 类的内部创建对象
  3. 向外暴露一个静态公共方法
public class Main {
   public static void main(String[] args) {
      Single s = Single.getSingle();
      Single s1 = Single.getSingle();
      System.out.println(s == s1);
   }
}
class Single {
   private final static Single s = new Single();
   private Single(){
   }
   public static Single getSingle(){

       return s;
   }
}
  1. 优点:类在装载的时候就已经拿到了类的实例化,避免了线程同步的问题。
  2. 缺点:在类加载就已经实例化了,没有达到 懒加载 的效果,如果没有用到这个实例那么就浪费了内存。
  3. 这个方法避免了类的多线程同步问题,但是可能会出现内存浪费

饿汉式(静态代码块)

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static Single s ;
    static {
        s = new Single();
    }

    private Single(){
    }
    public static Single getSingle(){

        return s;
    }
}
  1. 在类加载是通过静态代码块,对类进行了实例化。但是依然会有内存浪费的现象。

懒汉式(线程不安全)

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static Single s ;


    private Single(){

    }
    public static Single getSingle(){
        if(s == null){
            s = new Single();
        }

        return s;
    }
}
  1. 我们将对象实例化的过程放入对外暴露的静态方法中。
  2. 确实可以起到懒加载的效果。但是只能用于单线程。
  3. 但是如果在多线程下,多个线程同步判断 if(s == null)为true时,会对使其创建多个实例。

懒汉式(线程安全,同步方法)

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static Single s ;


    private Single(){

    }
    public static synchronized Single getSingle(){
        if(s == null){
            s = new Single();
        }

        return s;
    }
}
  1. 使用synchronized对同步线程进行处理
  2. 效率低,每个实例多需要调用getSingle方法时都要进行同步,但是这个只需要执行一次实例化代码就够了。

懒汉式(线程安全,同步代码块)

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static Single s ;


    private Single(){

    }
    public static synchronized Single getSingle(){
        if(s == null){
            synchronized(Single.class) {s = new Single();}
        }

        return s;
    }
}

1.虽然这里已经实现了在代码块中实现了线程安全,但是if(s == null)没有实现线程安全。

双重检查

线程对volatile变量的修改会立刻被其他线程所感知,即不会出现数据脏读的现象,从而保证数据的“可见性”。

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static volatile Single s ;


    private Single(){

    }
    public static synchronized Single getSingle(){
        if(s == null){
            synchronized(Single.class) {
                if(s==null){
                    s = new Single();
                }
            }
        }

        return s;
    }
}

静态内部类

public class Main {
    public static void main(String[] args) {
       Single s = Single.getSingle();
       Single s1 = Single.getSingle();
       System.out.println(s == s1);
    }
}
class Single {
    private  static volatile Single s ;


    private Single(){

    }
    private  static class SingleInstance{
        private  static final Single single = new Single();
    }
    public static synchronized Single getSingle(){

        return SingleInstance.single;
    }
}

静态内部类实现了懒加载,在装载类的时候是安全的所以也解决了线程同步问题。

枚举

public class Main {
    public static void main(String[] args) {
       Single s = Single.INSTANCE;
       Single s1 = Single.INSTANCE;
       System.out.println(s == s1);
    }
}
enum Single {
    INSTANCE;
    public void method(){

    }

}

1。可以使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值