终结23种设计模式-单列模式

1 单列模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

1 饿汉式

1
2
3
4
5
6
7
8
public class HungryManSingle {
   private static HungryManSingle hungryManSingle=new HungryManSingle();
   //构造方法私有
   private HungryManSingle(){}
   public static HungryManSingle getHungryManSingle(){
       return hungryManSingle;
   }
}

写出来之后:面试官问,为什么这个是线程安全的。

在线程访问单例对象之前就已经创建好了。再加上,由于一个类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例。也就是说,线程每次都只能也必定只可以拿到这个唯一的对象。即饿汉式单例天生就是线程安全的。

 饿汉式是当满足类加载条件的时候就在类加载过程中的初始化环节就完成了实例的创建(借此保证线程安全,即其他线程不会访问到还未初始化完毕的实例),因为类加载过程JVM会自动加锁,因此保证了单例特性。

2 懒汉式:线程不安全

1
2
3
4
5
6
7
8
9
10
11
12
13
public class LazySingleObjectNoSyn {
    private static LazySingleObjectNoSyn lazySingleObjectNoSyn;
     
    private LazySingleObjectNoSyn(){}
     
    public static LazySingleObjectNoSyn getLazySingleObjectNoSyn(){
        if(lazySingleObjectNoSyn ==null){
            lazySingleObjectNoSyn = new LazySingleObjectNoSyn();
        }
        return lazySingleObjectNoSyn;
    }
     
}

写出来之后:面试官问,这个为什么线程不安全

* 我们假设有多个线程1,线程2都需要使用这个单例对象。而恰巧,线程1在判断完s==null后突然交换了cpu的使用权,变为线程2执行,

* 由于s仍然为null,那么线程2中就会创建这个Singleton的单例对象。之后线程1拿回cpu的使用权,而正好线程1之前暂停的位置就是判断s是否为null之后,

* 创建对象之前。这样线程1又会创建一个新的Singleton对象。

3 懒汉式:线程安全 

1
2
3
4
5
6
7
8
9
10
11
public class LazySingleObjectSyn {
    private static LazySingleObjectSyn lazySingleObjectSyn;
    private LazySingleObjectSyn(){}
    public static synchronized LazySingleObjectSyn getLazySingleObjectSyn(){
        if (lazySingleObjectSyn==null){
            lazySingleObjectSyn=new LazySingleObjectSyn();
        }
        return lazySingleObjectSyn;
 
    }
}

4 双检锁/双重校验锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton { 
    private volatile static Singleton singleton; 
    private Singleton (){} 
    public static Singleton getSingleton() { 
    if (singleton == null) { 
        synchronized (Singleton.class) { 
        if (singleton == null) { 
            singleton = new Singleton(); 
        
        
    
    return singleton; 
    
}

5 静态内部内

1
2
3
4
5
6
7
8
9
public class StaticSingle {
    private StaticSingle() {}
    public static class Sin{
     private   final static  Sin sin=new Sin();
    }
   public static Sin getInstance(){
        return Sin.sin;
   }
}

6 枚举

1
2
3
4
5
public enum Singleton { 
    INSTANCE; 
    public void whateverMethod() { 
    
}

  

 

本文作者:KwFruit

本文链接:https://www.cnblogs.com/mangoubiubiu/p/14790944.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   KwFruit  阅读(91)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2020-05-20 第三方登录之sina
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起