当前位置: 首页 > news >正文

福州做网站/数据网站有哪些

福州做网站,数据网站有哪些,云主机推荐,自己做网站要学前端和后端Java中的单例模式 单例模式是 Java 中最简单的设计模式之一,它是指一个类在运行期间始终只有一个实例,我们就把它称之为单例模式。它不但被应用在实际的工作中,而且还是面试中最常考的题目之一。通过单例模式我们可以知道此人的编程风格&…

Java中的单例模式

单例模式是 Java
中最简单的设计模式之一,它是指一个类在运行期间始终只有一个实例,我们就把它称之为单例模式。它不但被应用在实际的工作中,而且还是面试中最常考的题目之一。通过单例模式我们可以知道此人的编程风格,以及对于基础知识的掌握是否牢固。

单例的实现方式有几种?它们有什么优缺点?

典型回答

单例的实现分为饿汉模式和懒汉模式。顾名思义,饿汉模式就好比他是一个饿汉,而且有一定的危机意识,他会提前把食物囤积好,以备饿了之后直接能吃到食物。对应到程序中指的是,在类加载时就会进行单例的初始化,以后访问时直接使用单例对象即可。

饿汉模式的实现代码如下:

public class Singleton {// 声明私有对象private static Singleton instance = new Singleton();    // 获取实例(单例对象)public static Singleton getInstance() {return instance;}private Singleton() {}// 方法public void sayHi() {System.out.println("Hi,Java.");}
}
class SingletonTest {public static void main(String[] args) {// 调用单例对象Singleton singleton = Singleton.getInstance();// 调用方法singleton.sayHi();}
}
以上程序的执行结果为:
Hi,Java.

从上述结果可以看出,单例对象已经被成功获取到并顺利地执行了类中的方法。它的优点是线程安全,因为单例对象在类加载的时候就已经被初始化了,当调用单例对象时只是把早已经创建好的对象赋值给变量;它的缺点是可能会造成资源浪费,如果类加载了单例对象(对象被创建了),但是一直没有使用,这样就造成了资源的浪费。

懒汉模式也被称作为饱汉模式,顾名思义他比较懒,每次只有需要吃饭的时候,才出去找饭吃,而不是像饿汉那样早早把饭准备好。对应到程序中指的是,当每次需要使用实例时,再去创建获取实例,而不是在类加载时就将实例创建好。

懒汉模式的实现代码如下:

public class Singleton {// 声明私有对象private static Singleton instance;// 获取实例(单例对象)public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}private Singleton() {}// 方法public void sayHi() {System.out.println("Hi,Java.");}
}
class SingletonTest {public static void main(String[] args) {Singleton singleton = Singleton.getInstance();singleton.sayHi();}
}
以上程序的执行结果为:Hi,Java.

从上述结果可以看出,单例对象已经被成功获取到并顺利地执行了类中的方法,它的优点是不会造成资源的浪费,因为在调用的时候才会创建被实例化对象;它的缺点在多线程环境下是非线程是安全的,比如多个线程同时执行到
if 判断处,此时判断结果都是未被初始化,那么这些线程就会同时创建 n 个实例,这样就会导致意外的情况发生。

考点分析
使用单例模式可以减少系统的内存开销,提高程序的运行效率,但是使用不当的话就会造成多线程下的并发问题。饿汉模式为最直接的实现单例模式的方法,但它可能会造成对系统资源的浪费,所以只有既能保证线程安全,又可以避免系统资源被浪费的回答才能彻底地征服面试官。

和此知识点相关的面试题还有以下这些:

什么是双重检测锁?它是线程安全的吗? 单例的还有其他实现方式吗? 知识扩展 双重检测锁
为了保证懒汉模式的线程安全我们最简单的做法就是给获取实例的方法上加上 synchronized(同步锁)修饰,如下代码所示:

public class Singleton {// 声明私有对象private static Singleton instance;// 获取实例(单例对象)public synchronized static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}

这样虽然能让懒汉模式变成线程安全的,但由于整个方法都被 synchronized 所包围,因此增加了同步开销,降低了程序的执行效率。

于是为了改进程序的执行效率,我们将 synchronized 放入到方法中,以此来减少被同步锁所修饰的代码范围,实现代码如下:

public class Singleton {// 声明私有对象private static Singleton instance;// 获取实例(单例对象)public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {instance = new Singleton();}}return instance;}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}

细心的你可能会发现以上的代码也存在着非线程安全的问题。例如,当两个线程同时执行到「if (instance == null) {
」判断时,判断的结果都为 true,于是他们就排队都创建了新的对象,这显然不符合我们的预期。于是就诞生了大名鼎鼎的双重检测锁(Double
Checked Lock,DCL),实现代码如下:

public class Singleton {// 声明私有对象private static Singleton instance;// 获取实例(单例对象)public static Singleton getInstance() {// 第一次判断if (instance == null) {synchronized (Singleton.class) {// 第二次判断if (instance == null) {instance = new Singleton();}}}return instance;}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}

上述代码看似完美,其实隐藏着一个不容易被人发现的小问题,该问题就出在 new 对象这行代码上,也就是 instance = new
Singleton()
这行代码。这行代码看似是一个原子操作,然而并不是,这行代码最终会被编译成多条汇编指令,它大致的执行流程为以下三个步骤:

给对象实例分配内存空间; 调用对象的构造方法、初始化成员字段; 将 instance 对象指向分配的内存空间。 但由于 CPU
的优化会对执行指令进行重排序,也就说上面的执行流程的执行顺序有可能是 1-2-3,也有可能是 1-3-2。假如执行的顺序是
1-3-2,那么当 A 线程执行到步骤 3 时,切换至 B 线程了,而此时 B 线程判断 instance
对象已经指向了对应的内存空间,并非为 null 时就会直接进行返回,而此时因为没有执行步骤
2,因此得到的是一个未初始化完成的对象,这样就导致了问题的诞生。执行时间节点如下表所示:

时间点 线程 执行操作 t1 A instance = new Singleton() 的 1-3 步骤,待执行步骤 2 t2 B if
(instance == null) {判断结果为 false t3 B 返回半初始的 instance 对象
为了解决此问题,我们可以使用关键字 volatile 来修饰 instance 对象,这样就可以防止 CPU
指令重排,从而完美地运行懒汉模式,实现代码如下:

public class Singleton {// 声明私有对象private volatile static Singleton instance;// 获取实例(单例对象)public static Singleton getInstance() {// 第一次判断if (instance == null) {synchronized (Singleton.class) {// 第二次判断if (instance == null) {instance = new Singleton();}}}return instance;}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}

单例其他实现方式 除了以上的 6 种方式可以实现单例模式外,还可以使用静态内部类和枚举类来实现单例。静态内部类的实现代码如下:

public class Singleton {// 静态内部类private static class SingletonInstance {private static final Singleton instance = new Singleton();}// 获取实例(单例对象)public static Singleton getInstance() {return SingletonInstance.instance;}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}

从上述代码可以看出,静态内部类和饿汉方式有异曲同工之妙,它们都采用了类装载的机制来保证,当初始化实例时只有一个线程执行,从而保证了多线程下的安全操作。JVM
会在类初始化阶段(也就是类装载阶段)创建一个锁,该锁可以保证多个线程同步执行类初始化的工作,因此在多线程环境下,类加载机制依然是线程安全的。

但静态内部类和饿汉方式也有着细微的差别,饿汉方式是在程序启动时就会进行加载,因此可能造成资源的浪费;而静态内部类只有在调用
getInstance()
方法时,才会装载内部类从而完成实例的初始化工作,因此不会造成资源浪费的问题。由此可知,此方式也是较为推荐的单例实现方式。

单例的另一种实现方式为枚举,它也是《Effective
Java》作者极力推荐地单例实现方式,因为枚举的实现方式不仅是线程安全的,而且只会装载一次,无论是序列化、反序列化、反射还是克隆都不会新创建对象。它的实现代码如下:

public class Singleton {// 枚举类型是线程安全的,并且只会装载一次private enum SingletonEnum {INSTANCE;// 声明单例对象private final Singleton instance;// 实例化SingletonEnum() {instance = new Singleton();}private Singleton getInstance() {return instance;}}// 获取实例(单例对象)public static Singleton getInstance() {return SingletonEnum.INSTANCE.getInstance();}private Singleton() {}// 类方法public void sayHi() {System.out.println("Hi,Java.");}
}
class SingletonTest {public static void main(String[] args) {Singleton singleton = Singleton.getInstance();singleton.sayHi();}
}
以上程序的执行结果为:Hi,Java.

小结 本课时我们讲了 8 种实现单例的方式,包括线程安全但可能会造成系统资源浪费的饿汉模式,以及懒汉模式和懒汉模式变种的 5
种实现方式。其中包含了两种双重检测锁的懒汉变种模式,还有最后两种线程安全且可以实现延迟加载的静态内部类的实现方式和枚举类的实现方式,其中比较推荐使用的是后两种单例模式的实现方式。

http://www.jmfq.cn/news/5160133.html

相关文章:

  • jsp网站开发学习心得/营销策划推广
  • 找人做seo要给网站程序/百度网站禁止访问怎么解除
  • 深圳营销型网站联系方式/深圳网络seo推广
  • 网站建设要学哪些/品牌营销策划怎么写
  • 可以做音乐mv视频网站/网站如何快速推广
  • 建网站需要了解什么/阿里数据
  • 做网站有陪标现象吗/广告推广投放平台
  • 独立设计师平台/太原网站建设优化
  • 网站开发 网页设计/seo推广招聘
  • 平面设计软件下载网站/如何制作微信小程序
  • 做网站怎么调用栏目/市场营销七大策略
  • 旅游攻略网站开发背景/靠谱的代运营公司
  • 番禺有经验的网站建设/搜索引擎的工作原理分为
  • abc官网/app优化
  • 深圳哪做网站/谷歌chrome手机版
  • 关于网站建设新闻/新浪nba最新消息
  • 做外汇网站做什么类型网站好/百度极速版推广
  • 外包网站设计/百度推广登录首页网址
  • 娄底手机网站制作/网站的推广方法有哪些
  • 建立视频网站/东莞市民最新疫情
  • 湘潭城乡建设发展集团网站/太原seo外包服务
  • 深圳网站建设哪家公司好/百度平台客服电话
  • java 网站开发教程 pdf/晋江友情链接是什么意思
  • 网站设计开发软件网页美化工具/今天今日新闻头条最新消息
  • 音乐网站素材/推广代理平台
  • 那个网站可以接做网页私活/谷歌商店paypal官网下载
  • 电商网站开发哪里好/数字化营销怎么做
  • 中国林业工程建设协会网站/五八精准恶意点击软件
  • 纯css做网站/站长之家网站流量查询
  • 做贺卡的网站/电商网店