单例模式的5种实现方法-设计模式
1.双重检查的方式
特点:线程安全;延迟加载;效率较高,推荐使用
/**
* 双重检查的方式,线程安全;延迟加载;效率较高。
* @author LENOVO
*
*/
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
2.静态内部类
特点:延时加载,线程安全,效率高
/**
* 静态内部类的方式,延时加载,线程安全,效率高
* @author LENOVO
*/
public class Singleton2 {
private Singleton2() {}
private static class SingletonInstance {
private static final Singleton2 INSTANCE = new Singleton2();
static {
System.out.println(INSTANCE);
}
}
public static Singleton2 getInstance() {
System.out.println("****");
return SingletonInstance.INSTANCE;
}
public static void main(String[] args) {
Singleton2.getInstance();
/**
* 为什么说是延时加载呢?
* 静态变量在类加载完成以后就完成了初始化,但在本例当中
* 在没有调用getInstance方法之前,SingletonInstance类是不会被虚拟机加载的。
* 当调用getInstance方法,执行return SingletonInstance.INSTANCE;语句时,
* 虚拟机才会去加载SingletonInstance类,并完成INSTANCE实例的初始化。
*/
}
}
3.饿汉式(静态常量)
/**
* 饿汉式(静态常量),在类加载的时候完成初始化
* @author LENOVO
*/
public class Singleton3 {
private final static Singleton3 INSTANCE = new Singleton3();
private Singleton3(){}
public static Singleton3 getInstance(){
return INSTANCE;
}
}
4.懒汉式(延时加载【不推荐用】)
/**
* 懒汉式(延时加载【不推荐用】)
* @author LENOVO
*
*/
public class Singleton4 {
private static Singleton4 Singleton4;
private Singleton4() {}
/**
* 线程不安全
* @return
*/
public static Singleton4 getInstance() {
if (Singleton4 == null) {
Singleton4 = new Singleton4();
}
return Singleton4;
}
/**
* 线程安全,但是效率底
* @return
*/
public static synchronized Singleton4 getInstance2() {
if (Singleton4 == null) {
Singleton4 = new Singleton4();
}
return Singleton4;
}
/**
* 线程不安全效率底,这种方法不能起到线程同步的效果
* @return
*/
public static Singleton4 getInstance3() {
if (Singleton4 == null) {
synchronized (Singleton4.class) {
Singleton4 = new Singleton4();
}
}
return Singleton4;
}
}
5.枚举实现单例模式
枚举的方式实现是最安全的
public enum Singleton5 {
INSTANCE;
public int i = 0;
public void leaveTheBuilding() {
i++;
System.out.println("我现在是单例,这是我第"+i+"次调用!!");
}
// 调用这样子调用
public static void main(String[] args) {
for(int z = 0 ; z<10 ;z++){
Singleton5 demo = Singleton5.INSTANCE;
demo .leaveTheBuilding();
}
}
}
猜你喜欢
blog
java启动线程的两种方式
java基础
3059
java启动线程的三种方式1.继承Thread类,重写run方法,调用start方法启动线程2.实现Runnable接口,重写run方法,调用start方法启动线程3.实现Callable接口代码如
blog
redis哨兵模式环境搭建
redis
161
介绍 单机版的Redis存在性能瓶颈,Redis通过提高主从复制实现读写分离,提高了了Redis的可用性,另一方便也能实现数据在多个Redis直接的备份。 通过配置Redis的主从复制机制可以提
blog
java线程通讯之生产者消费者模式
java基础
876
java线程通讯之生产者消费者模式生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。一个生产和消
official
452
上一篇文章《(mq)rabbitmq消息发送确认》介绍了消息发布时的确认方案,本篇文章将介绍,消息消费确认的方法。和确认发布一样,消费者有时也需要确认,rabbitmq有三种确认模式
official
527
一、什么是bio?bio即:同步阻塞式IO。就是传统的javaio网络模型。javabio有两个阻塞的地方,第一个地方是需要阻塞的监听端口,等待客户端链接。第二个需要阻塞Socket的read方法
blog
spring aop实现操作日志记录
框架
3118
springaop实现操作日志记录此次的目的是实现对controller中的方法执行情况进行记录,记录的有方法执行时间,操作人,请求的路径,方法的入参,模块,功能等。并实现利用注解的方式实现对被操作
blog
java使用欧几里得算法计算比例的方法
数据结构与算法
1018
java使用欧几里得算法计算比例的方法 publicstaticvoidmain(String[]args){ System.out.println(bili(2,6
blog
asm实例对象方法的调用
java基础
2407
asm实例对象方法的调用1.需要的jar包2.我们需要通过asm生成的目标类如下:packageclub.jiajia.test3;publicclassExamp5
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。