Singerw's Repository Singerw's Repository
首页
  • 相关文章

    • HTML相关文章
    • CSS相关文章
    • JavaScript相关文章
  • 学习笔记

    • JavaScript笔记
    • ES6笔记
    • Vue笔记
  • 相关文章

    • Spring相关文章
    • SpringBoot相关文章
    • MyBatis相关文章
    • MySQL相关文章
  • 学习笔记

    • SpringBoot笔记
    • Spring笔记
    • MyBatis笔记
    • MySQL笔记
    • JavaWeb笔记
    • JavaCore笔记
  • 学习笔记

    • Linux笔记
    • Git笔记
    • 技术文档
  • 偏门技术

    • GitHub技巧
    • 博客搭建
    • 科学上网
  • 安装教程

    • JDK
    • MySQL
    • Node.js
    • Linux
  • 终身学习
  • 面试人生
  • 心情杂货
  • 生活随笔
  • 归档
  • 标签
GitHub (opens new window)

Singerw

谁能够凭爱意将富士山私有
首页
  • 相关文章

    • HTML相关文章
    • CSS相关文章
    • JavaScript相关文章
  • 学习笔记

    • JavaScript笔记
    • ES6笔记
    • Vue笔记
  • 相关文章

    • Spring相关文章
    • SpringBoot相关文章
    • MyBatis相关文章
    • MySQL相关文章
  • 学习笔记

    • SpringBoot笔记
    • Spring笔记
    • MyBatis笔记
    • MySQL笔记
    • JavaWeb笔记
    • JavaCore笔记
  • 学习笔记

    • Linux笔记
    • Git笔记
    • 技术文档
  • 偏门技术

    • GitHub技巧
    • 博客搭建
    • 科学上网
  • 安装教程

    • JDK
    • MySQL
    • Node.js
    • Linux
  • 终身学习
  • 面试人生
  • 心情杂货
  • 生活随笔
  • 归档
  • 标签
GitHub (opens new window)
  • Java 核心语法
  • Java 流程控制
  • Java 数组
  • Java 面向对象
  • Java 集合框架
  • Java 深入面向对象
  • Java 常用类(API)
  • Java 内部类
  • 深入理解 Java 异常
  • Java IO流
  • Java 多线程
  • Java 网络编程
  • Java 设计模式
    • 一、 单例模式
      • 1.1 饿汉式
      • 1.2 懒汉式
      • 1.3 静态内部类模式
      • 1.4 双重锁的形式
    • 二、适配器模式
    • 三、工厂模式
  • 深入了解序列化
  • DBUtil 手写工具类
  • 《JavaCore》学习笔记
Singerw
2021-08-22

Java 设计模式

# Java 设计模式

# 一、 单例模式

# 1.1 饿汉式

懒汉式的实现思路是:饿汉根本等不及别人来找他,不管三七二十一先初始化了自身的实例,生怕自己饿着了。

类默认先直接初始化一个实例,以后调用 getInstance() 总是返回这个已创建好的实例。

缺点:在没有必要获取实例时,已经预先产生了开销。

优点:规避了懒汉式方法的线程问题,不用显示编写线程安全代码。

类形式:构造方法私有化,公共静态方法返回对象

  • 构造私有化
  • 类加载执行
  • 提供一个公共静态方法供外部方法
package com.singerw.designpatterndemo;

/**
 * @Author: CodeSleep
 * @Date: 2021-06-21 14:01
 * @Description: //TODO 单例模式 ==> 饿汉模式
 */
public class SingIeton {

    /**
     * 2.声明Singleton2
     */
    private static SingIeton s = new SingIeton();


    /**
     * @Author CodeSleep
     * @Date: 2021-06-21 14:03
     * @Description: //TODO  1.通过对构造访问权限的控制,我们将方法私有化后,为不能直接new
     */
    private SingIeton() {
    }

    /**
     * @return 返回值是SingIeton;返回值是私有属性 SingIeton s
     * @Author CodeSleep
     * @Date: 2021-06-21 14:16
     * @Description: //TODO 3.提供一个公共静态方法供外部方法,
     */
    public synchronized static SingIeton getInstance() {
        return s;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 1.2 懒汉式

懒汉式的实现思路是:你不找懒汉,懒汉根本就懒得去初始化自己。

instance 初始时没有初始化,只有当第一次调 getInstance() 时才创建实例。

缺点:当有两个线程调 getInstance() 方法,当它们同时执行到 if (null == instance) 这行代码,instance 为 null。

继续向下执行,会生成两个实例,违背了单例模式的初衷。

package com.singerw.designpatterndemo;

/**
 * @Author: CodeSleep
 * @Date: 2021-06-21 14:01
 * @Description: //TODO 单例模式 ==> 懒汉模式
 */
public class SingIeton2 {
    /**
     * 2.申明 SingIeton2
     */
    private static SingIeton2 s = null;


    /**
     * @Author CodeSleep
     * @Date: 2021-06-21 14:03
     * @Description: //TODO  1.通过对构造访问权限的控制,我们将方法私有化后,为不能直接new
     */
    private SingIeton2() {
    }

    /**
     * @return 返回值是SingIeton2;返回值是私有属性 SingIeton2 s
     * synchronized 支持线程同步
     * @Author CodeSleep
     * @Date: 2021-06-21 14:13
     * @Description: //TODO 3.提供一个公共静态方法供外部方法,
     */
    public synchronized static SingIeton2 getInstance() {
        // 判断s 是否为Null
        if (s == null) {
            // 如果为null,则实例化SingIeton2
            s = new SingIeton2();
        }
        return s;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 1.3 静态内部类模式

package com.singerw.designpatterndemo;

/**
 * @author Administrator
 */

/**
 * @Author: CodeSleep
 * @Date: 2021-06-22 9:11
 * @Description: //TODO 懒汉方式来实现单例模式  懒加载 (静态内部类)
 *
 */
public class SingIeton3 {

    /**
     * @Author CodeSleep
     * @Date: 2021-06-22 9:10
     * @Description: //TODO 2 声明 Singleton3
     * 外部类加载,这个内部类SingletonHolder ->不执行的 =>依然满足懒加载
     */
    private static class SingletonHolder {
        //只执行一次
        private static SingIeton3 s = new SingIeton3();
    }


    /**
     * @Author CodeSleep
     * @Date: 2021-06-22 9:10
     * @Description: //TODO 1. 通过对构造访问权限控制,我们将方法私有化后,外部不能直接new .
     */
    private SingIeton3() {
        System.out.println("private Singleton3");
    }

    /**
     * synchronized 支持线程同步
     *
     * @return Singleton s
     * @Author CodeSleep
     * @Date: 2021-06-22 9:09
     * @Description: //TODO 3.提供一个公共静态方法供外部访问,返回值类型是Singleton;返回值是私有属性 Singleton s
     */
    public static SingIeton3 getInstance() {
        //当getInstance被调用的时候(第一次被调用的时候),调用上面的类,那么SingletonHolder就会被加载,进入SingletonHolder静态的实例化
        return SingletonHolder.s;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 1.4 双重锁的形式

如果既不想在没有调用 getInstance() 方法时产生开销,又不想发生线程安全问题,就可以采用双重锁的形式。

public class SyncSingleton {
    private SyncSingleton() {
        System.out.println("Singleton()");
    }

    private static SyncSingleton instance = null;

    public static SyncSingleton getInstance() {
        if (null == instance) {
            synchronized(SyncSingleton.class) {
                if (null == instance) {
                    instance = new SyncSingleton();
                }
            }
        }
        return instance;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注:在外面判断了 instance 实例是否存在,为什么在锁定后又要在内部又判断一次?

这是因为,如果 instance 为 null 时有两个线程同时调用 getInstance(),由于 synchronized 机制,只允许一个线程进入,另一个需要等待。

这时如果没有第二道 instance 是否为 null 的判断,就可能发生第一个线程创建一个实例,而第二个线程又创建一个实例的情况。

# 二、适配器模式

# 三、工厂模式

编辑 (opens new window)
#JavaCore
Java 网络编程
深入了解序列化

← Java 网络编程 深入了解序列化→

最近更新
01
Maven资源导出问题终极版
10-12
02
《MyBatis-Plus》学习笔记
10-07
03
MyBatis-Plus—配置日志
10-07
更多文章>
Theme by Vdoing | Copyright © 2020-2021 版权所有 | repository.singerw.com
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×