设计模式之单例模式
单例模式
饿汉式
缺点:不管使用与否,类装载时就完成实例化
优点: 实现简单
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之饿汉式
*
* 类加载到内存时,就会实例化一个单例,JVM保证了线程安全。
* 实现简单,推荐使用
* 唯一的缺点:不管使用与否,类装载时就完成实例化
*
*/
public class Mgr01 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static final Mgr01 INSTANCE=new Mgr01();
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr01(){}
/**
* 获取该实例的唯一途径
* @return
*/
public static Mgr01 getInstance(){
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
* @param args
*/
public static void main(String[] args) {
Mgr01 instance1 = Mgr01.getInstance();
Mgr01 instance2 = Mgr01.getInstance();
// 返回结果为true
System.out.println(instance1==instance2);
}
}
静态代码块实现方式
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之饿汉式
*
* 类加载到内存时,就会实例化一个单例,JVM保证了线程安全。
* 实现简单,推荐使用
* 唯一的缺点:不管使用与否,类装载时就完成实例化
*
*/
public class Mgr02 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static final Mgr02 INSTANCE;
static {
INSTANCE=new Mgr02();
}
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr02(){}
/**
* 获取该实例的唯一途径
* @return
*/
public static Mgr02 getInstance(){
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
* @param args
*/
public static void main(String[] args) {
Mgr02 instance1 = Mgr02.getInstance();
Mgr02 instance2 = Mgr02.getInstance();
// 返回结果为true
System.out.println(instance1==instance2);
}
}
懒汉式
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之懒汉式
* <p>
* 虽然达到了按需使用目的,但是带来了线程不安全
*/
public class Mgr03 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static Mgr03 INSTANCE;
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr03() {
}
/**
* 获取该实例的唯一途径
*
* @return
*/
public static Mgr03 getInstance() {
if (null == INSTANCE) {
try {
Thread.sleep(1);
}catch (Exception e){
}
return new Mgr03();
}
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()-> {
System.out.println(Mgr03.getInstance().hashCode());
}).start();
}
}
}
添加锁
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之懒汉式
* <p>
* 虽然达到了按需使用目的,但是带来了线程不安全
* 可以通过添加synchronized解决,但是也带来了效率下降
*/
public class Mgr04 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static Mgr04 INSTANCE;
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr04() {
}
/**
* 获取该实例的唯一途径
* static 方法使用的锁定的是当前对象的class对象。
*
* @return
*/
public static synchronized Mgr04 getInstance() {
if (null == INSTANCE) {
try {
Thread.sleep(1);
}catch (Exception e){
e.printStackTrace();
}
return new Mgr04();
}
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()-> {
System.out.println(Mgr04.getInstance().hashCode());
}).start();
}
}
}
在有需要的地方添加锁,提高性能
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之懒汉式
* <p>
* 虽然达到了按需使用目的,但是带来了线程不安全
* 可以通过添加synchronized解决,但是也带来了效率下降
*/
public class Mgr05 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static Mgr05 INSTANCE;
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr05() {
}
/**
* 获取该实例的唯一途径
* static 方法使用的锁定的是当前对象的class对象。
*
* @return
*/
public static Mgr05 getInstance() {
if (null == INSTANCE) {
synchronized (Mgr05.class) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
return new Mgr05();
}
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(Mgr05.getInstance().hashCode());
}).start();
}
}
}
双重判断添加锁(Double check lock. DCL)
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之懒汉式
* <p>
* 虽然达到了按需使用目的,但是带来了线程不安全
* 可以通过添加synchronized解决,但是也带来了效率下降
*/
public class Mgr06 {
/**
* 类加载的时候初始化一个实例,放在内存中
*/
private static volatile Mgr06 INSTANCE;
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr06() {
}
/**
* 获取该实例的唯一途径
* static 方法使用的锁定的是当前对象的class对象。
*
* @return
*/
public static Mgr06 getInstance() {
if (null == INSTANCE) {
synchronized (Mgr06.class) {
if (null == INSTANCE) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return new Mgr06();
}
return INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(Mgr06.getInstance().hashCode());
}).start();
}
}
}
静态内部类
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之静态内部类
* <p>
* jvm保证单例
* 加载外部类时不会加载内部类,这样可以实现懒加载。
*/
public class Mgr07 {
/**
* 私有化空参构造方法,使其无法创建对象
*/
private Mgr07() {
}
private static class Mgr07Holder{
private final static Mgr07 INSTANCE=new Mgr07();
}
/**
* 获取该实例的唯一途径
* static 方法使用的锁定的是当前对象的class对象。
*
* @return
*/
public static Mgr07 getInstance() {
return Mgr07Holder.INSTANCE;
}
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(Mgr07.getInstance().hashCode());
}).start();
}
}
}
枚举
package com.example.designer.singleton;
/**
* @version 1.0
* @create 2022/10/1 00:08
* @description 单例设计模式之枚举
* <p>
* 这种是最完美的,还可以防止反序列化
*
* 枚举没有构造方法。不可以进行反序列化。
*/
public enum Mgr08 {
INSTANCE;
/**
* 校验获取到的实例对象就是一个对象。
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(Mgr08.INSTANCE.hashCode());
}).start();
}
}
}
本文来自博客园,作者:King-DA,转载请注明原文链接:https://www.cnblogs.com/qingmuchuanqi48/articles/16746606.html

浙公网安备 33010602011771号