单例模式
设计模式总分类分类
创建型模式( 5种 )
- 单例模式
- 工厂模式
- 抽象工厂模式
- 建造者模式
- 原型模式
结构型模式( 7种 ):
- 适配器模式
- 桥接模式
- 装饰模式
- 组合模式
- 外观模式
- 享元模式
- 代理模式
行为型模式( 11种 ):
- 模版方法模式
- 命令模式
- 迭代器模式
- 观察者模式
- 中介者模式
- 备忘录模式
- 解释器模式
- 状态模式
- 策略模式
- 职责链模式
- 访问者模式
单例模式
作用
保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
应用场景
优势
只生产一个实例 ,减少系统开销
单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计 一个单例类,负责所有数据表的映射处理
当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动 时直接产生一个单例对象,然后永久驻留内存的方式来解决
单例模式五种实现方式
饿汉式
package ah.szxy.singleton;
/**
* 单例模式-饿汉式
*
* 创建一个类的对象并初始化
* 创建一个获取它的方法,返回这对象
*
* @author chy
*
*/
public class SingletonDemo1 {
//类初始化时,类加载时这个对象就被加载 ,线程安全 ,但无延迟加载优势
private static SingletonDemo1 instance=new SingletonDemo1();
//方法没有同步 ,调用效率高
public static SingletonDemo1 getInstance() {
return instance ;
}
private SingletonDemo1() { };
}
懒汉式
package ah.szxy.singleton;
/**
* 单例模式-懒汉式
*
* 声明一个类的对象 ,不初始化
* 创建一个获取该类的方法(线程锁) ,如果对象不为空就进行初始化,为空则直接返回
*
* @author chy
*
*/
public class SingletonDemo2 {
//类初始化时 ,不加载这个变量 .延时加载,用到再加载
private static SingletonDemo2 instance;
//线程锁 ,使方法同步 ,调用效率低
public static synchronized SingletonDemo2 getInstance() {
if (instance==null) {
instance=new SingletonDemo2() ;
}
return instance;
}
private SingletonDemo2() { };//私有化构造器
}
静态内部类式
package ah.szxy.singleton;
/**
* 单例模式-静态内部类方式
*
* 创建一个静态内部类 ,内部类中创建一个类的对象并初始化
* 创建一个获取这个类的方法,通过调用内部类返回这个类的对象
*
* @author chy
*
*/
public class SingletonDemo4 {
private static class SingletonClassInstance {
private static final SingletonDemo4 instance = new SingletonDemo4();
}
public static SingletonDemo4 getInstance() {
return SingletonClassInstance.instance;
}
private SingletonDemo4() { }
}
双重检测锁
package ah.szxy.singleton;
/**
* 单例模式-双重检测锁
*
* 先创建一个类的对象不初始化
* 静态方法没加锁 ,通过if进行判断
* 如果对象为空 ,在声明这个类是进行加上锁
* 声明的对象为空,在初始化时加锁
*
* @author chy
*
*/
public class SingletonDemo3 {
private static SingletonDemo3 instance = null;
public static SingletonDemo3 getInstance() {
if (instance == null) {
SingletonDemo3 sc;
synchronized (SingletonDemo3.class) {
sc = instance;
if (sc == null) {
synchronized (SingletonDemo3.class) {
if (sc == null) {
sc = new SingletonDemo3();
}
}
instance = sc;
}
}
}
return instance;
}
private SingletonDemo3() {
}
}
枚举式
package ah.szxy.singleton;
/**
* 单例模式-枚举式
*
* 声明一个enum类型的类
* 声明一个枚举元素
* 声明一个枚举类型的方法,根据需要添加内容
*
* @author 曹海洋
*
*/
public enum SingletonDemo5 {
//枚举元素 ,本身就是单例对象
INSTANCE;
//添加自定义操作
public void SingletonOperator() {
}
}
测试类
package ah.szxy.singleton;
import java.util.concurrent.CountDownLatch;
public class Client {
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
int threadNum=10;//线程计数器
//CountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其它线程完成它们的操作。
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
for (int i = 0; i < threadNum; i++) {
new Thread(new Runnable() {//创建了一个线程
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
SingletonDemo4 o = SingletonDemo4.getInstance();
}
countDownLatch.countDown();
}
}).start();
}
countDownLatch.await();//主线程阻塞后,直到计数器变为0,才会继续相信执行
long end =System.currentTimeMillis();
System.out.println("总时长"+(end-start));
}
}
测试结果会因为每台主机的性能原因而不同, 这里只做参考
CountDownLatch : 同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一 个或多个线程一直等待。
• countDown() 当前线程调此方法,则计数减一(建议放在 finally里执行)
• await(), 调用此方法会一直阻塞当前线程,直到计时器的值为0
五种单例模式总结
重点掌握饿汉式 , 懒汉式 ,静态内部类式
单例模式选取策略
来源:https://blog.csdn.net/qq_43371556/article/details/99695677