JAVA设计模式---单例模式你知道吗
目录
- 单例模式的介绍
- 单例模式实现的八种方式
- 饿汉式
- 静态常量
- 静态代码块
- 懒汉式
- 线程不安全的写法
- 线程安全,同步锁—效率低,不推荐
- 线程安全,同步代码块—无法解决线程安全问题,不推荐
- 双重检查—解决线程安全和懒加载问题–推荐使用
- 静态内部类—可以实现懒加载,线程安全,推荐使用
- 枚举
- 单例模式注意事项
- 总结
单例模式的介绍
文章图片
单例模式实现的八种方式
文章图片
饿汉式
【JAVA设计模式---单例模式你知道吗】
静态常量 步骤:
1.构造器私有化(防止new)
2.类的内部创建对象
3.向外暴露一个静态的公共方法—getInstance
//饿汉式静态常量class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量private final staticSingletoninstance=new Singleton(); //提供一个公有的静态方法,返回一个实例对象public static Singleton getInstance(){return instance; }}public class Main{public static void main(String[] args){Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
文章图片
静态代码块
//饿汉式静态常量class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量private staticSingletoninstance; //在静态代码块中,创建单例对象static{instance=new Singleton(); }//提供一个公有的静态方法,返回一个实例对象public static Singleton getInstance(){return instance; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
静态代码块的优缺点
文章图片
懒汉式
线程不安全的写法
class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量private staticSingletoninstance; //提供一个公有的静态方法//当使用该方法时,才去创建实例对象//即懒汉式public static Singleton getInstance(){if(instance==null){instance=new Singleton(); }return instance; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
线程安全,同步锁—效率低,不推荐
class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量private staticSingletoninstance; //提供一个公有的静态方法//当使用该方法时,才去创建实例对象//即懒汉式//给当前静态方法加上一个同步锁,这样所有的对象就是一把锁//多个对象同时调用此方法,会按顺序依次调用public static synchronized Singleton getInstance(){if(instance==null){instance=new Singleton(); }return instance; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
线程安全,同步代码块—无法解决线程安全问题,不推荐
class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量private staticSingletoninstance; //提供一个公有的静态方法//当使用该方法时,才去创建实例对象//即懒汉式public staticSingleton getInstance(){if(instance==null){//锁的是代码块//锁的对象是当前类的字节码文件对象,即当前类的所有势力对象拥有一把锁synchronized(Singleton.class){instance=new Singleton(); }}return instance; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
双重检查—解决线程安全和懒加载问题–推荐使用
class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态常量//volatile 保证变量在多线程下的可见性,即每个线程获取到当前变量的值是最新的值private staticvolatile Singletoninstance; //提供一个公有的静态方法//当使用该方法时,才去创建实例对象public staticSingleton getInstance(){//加入双重检查问题,解决线程安全,同时解决懒加载问题if(instance==null){//锁的是代码块//锁的对象是当前类的字节码文件对象,即当前类的所有势力对象拥有一把锁synchronized(Singleton.class){if(instance==null){instance=new Singleton(); }}}return instance; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
静态内部类—可以实现懒加载,线程安全,推荐使用
静态内部类在调用时,才会加载
当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的
class Singleton{//构造器私有化,外部不能newprivate Singleton(){}//静态内部类private static class SingletonInstance{//静态属性private static final Singleton INSTANCE=new Singleton(); }public staticSingleton getInstance(){//该方法调用时,静态内部类加载,里面的静态属性才会赋值return SingletonInstance.INSTANCE; }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
枚举
enum Singleton{//枚举常量INSTANCE; //底层: public static final Singleton INSTANCE= new Singleton (); //方法public void getInstance(){System.out.println("得到实例"); }}public class Main{public static void main(String[] args) {Singleton s1=Singleton.INSTANCE; Singleton s2=Singleton.INSTANCE; s1.getInstance(); s2.getInstance(); System.out.println(s1.hashCode()==s2.hashCode()); }}
优缺点
文章图片
单例模式注意事项
文章图片
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用