Maison> Java> javaDidacticiel> le corps du texte

浅谈Java中几种常用设计模式之单例模式

无忌哥哥
Libérer: 2018-07-23 11:25:10
original
1641 Les gens l'ont consulté

一、单例模式

是Java多种设计模式中较为常用的一种,在它的核心结构中只包含了一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类只有一个实例。

二、模式要求

1、自己的构造方法必须私有化

2、类的内部自己创建一个自己唯一的实例

3、要提供一个公开的静态方法供其他对象获取该实例

三、几种实现方式

饿汉式

public class Simple { private static Simple simple = new Simple(); private Simple() { } public static Simple getInstance() { return simple; } }
Copier après la connexion

这种实现方式在类加载时进行实例化,没有延迟加载,是线程安全的。

懒汉式

public class Slacker { private static volatile Slacker slacker = null; private Slacker() { } /** * 最简单的懒汉式实现 * @return */ public static Slacker getInstance() { if(slacker == null) { slacker = new Slacker(); } return slacker; } }
Copier après la connexion

这种实现方式是最基本的实现,最大的问题是不支持多线程,并发访问方法会获得不止一个实例,所以严格来讲不是单例模式。

public class Slacker { //volatile关键字的作用 //1、保证内存可见性:保证每个线程访问volatile修饰的共享变量时获取到的都是最新的。 //2、防止指令重排序--通过内存屏障实现 private static volatile Slacker slacker = null; private Slacker() { } /** * 加synchronized关键字解决线程同步问题 * @return */ public static synchronized Slacker getInstanceSync() { if(slacker == null) { slacker = new Slacker(); } return slacker; } }
Copier après la connexion

这种通过在方法上加synchronized锁实现的方式,可以解决线程并发访问的问题,实现单例,但是加锁后会影响效率,所以往往不这样使用。

双重检查锁

public class Slacker { //volatile关键字的作用 //1、保证内存可见性:保证每个线程访问volatile修饰的共享变量时获取到的都是最新的。 //2、防止指令重排序--通过内存屏障实现 private static volatile Slacker slacker = null; private Slacker() { } /** * 双重检查锁解决线程同步问题 * @return */ public static Slacker getInstanceDoubleLock() { if(slacker == null) { synchronized (Slacker.class) { if(slacker == null) { slacker = new Slacker(); } } } return slacker; } }
Copier après la connexion

这种方式采用双锁机制,能够适应多线程并发访问的情况,且能保持高性能。

静态内部类实现

/** * 静态内部类方式实现单例模式 * * 当StaticInnerClass第一次被加载时,并不需要去加载StaticInnerClassHoler,只有当getInstance()方法第一次被调用时, * 才会去初始化staticInnerClass,第一次调用getInstance()方法会导致虚拟机加载StaticInnerClassHoler类,这种方法不仅能 * 确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。 * * @author chenf * */ public class StaticInnerClass { private StaticInnerClass() { } // 静态内部类 private static class StaticInnerClassHoler { // 在静态内部类中定义外部类的实例 private static StaticInnerClass staticInnerClass = new StaticInnerClass(); } /** * 获取时调用静态内部类的类属性获取外部类的实例 * * @return */ public static StaticInnerClass getInstance() { return StaticInnerClassHoler.staticInnerClass; } }
Copier après la connexion

这种方式不仅可以实现多线程的安全访问,同时还可以使用内部类加载机制达到延迟加载的目的。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!