我是靠谱客的博主 强健大叔,最近开发中收集的这篇文章主要介绍Java多线程之实现单例模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是单例模式

  • 首先我们先了解一下什么是单例模式,其实单例模式是创建类型的一种常用的软件设计模式,也是我们多线程编程中用的最多,最重要的一种设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)
  • 其实最简单的理解就是顾名思义,单例模式就是只有一个实例化对象。

单例模式的实现方式

  • 饿汉模式

     饿汉模式就是再类加载的时候就把对象创建好,不管用不用都会被创建
    
class Test{
//单例模式之饿汉模式
private static Test t = new Test();
private Test() {}
//把构造方法私有化,禁止类外部
private static Test getTest(){
return t;
}
}
  • 懒汉模式

    
    懒汉模式就是什么时候调用,什么时候创建,相比于饿汉模式效率比较高,不会浪费空间内存
    
 class Test2{
//单例模式之懒汉汉模式
private static Test2 t = null;
private Test2() {}
private static Test2 getTest(){
if(t == null) {
t = new Test2();
//只有第一次调用getTest才会new一个新对象,之后再调用就会直接返回第一次创建好的。
}
return t;
}
}

-双检模式

public class Singleton {
public static volatile Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
//采用两个if可以解决第二次调用的时候会触发获取锁的操作;
if (instance == null) {
synchronized (Singleton.class) {
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
  • 我们之前已经了解过饿汉模式和懒汉模式了,那我们的双检模式和前两个模式的区别就在于多了一个synchornized代码块,然后多了两个 if 判断语句,多了个volatile关键字

synchornized代码块

首先我们说为什么要用synchornized锁,当有两个线程同时执行了getIntance方pan创建对象的时

候,这个时候intance是null,然后两个线程就会同时new出来两个新对象,然后返回,这就失去了我们

单例模式的意义。当我们加上锁之后,当第一个线程正在执行获取到锁的时候,线程2就会等待,等线

程1结束的时候,线程2就会获取到锁,然后判断intance不为空,就会返回线程1已经创建好的对象,**

这就保证了多线程并发执行getInstace方法的时候,仍然能保证是单例模式**;

双if语句(双检)

然后我们说为什么要用两个 if 语句,synchornized锁里面 if 语句我们已经知道作用了,防止重复创建

实例化对象。如果我们不用synchornized外面的 if ,那么程序每次都会获取锁,释放锁,然后再判断

instance是否为空,程序每次释放锁,获取锁也是会很耗费系统的资源,影响程序的效率,再加一个 if

的话,当instance不为空,也不用获取锁,会直接返回之前创建好的。**这样做能避免程序进行无意义

的获取释放锁**,极高的提高程序的执行效率。

volatile关键字

我们之所以在单例模式中使用volatile,是为了解决jvm指令重排序带来的问题。并不是为了解决内存可见性问题,synchornized已

经为我们解决了内存可见性问题。

例如 instance = new Singleton();这个操作就不是原子性的,它的执行过程如下:

  1. 给instance分配内存
  2. 调用Singleton的构造函数进行初始化
  3. 将instance对象指向分配的内存空间

经过我们JVM优化之后,顺序就可能变成1,3,2,即先将instance指向未初始化完成的内存空间,只有执行完第三步之后,

instance才不为空

如此此时线程A先将instance指向未初始化完成的内存空间,然后线程B执行getInstance方法,获取到instance不为空返回,此时

获取到的instance就是未初始化完成的,调用的时候就会出错。

单例模式的作用

我们实现单例模式的目的是为了什么,为了让程序中只有一个实例化对象(比如某个大型服务器中存了大量的数据,我们的服务

器程序不想让系统中存在太多这样重复的大对象),之所以设计这种模式,是因为如果我们手动控制让一个类只被new一次,不

被重复new,要靠程序员手工去实现,但是这样是不太靠谱的。而我们实现了单例模式后,单例模式就可以让编辑器自动帮我们

做更充分的检查,类似于编辑器会自动检查final,abstract关键字一样。

最后

以上就是强健大叔为你收集整理的Java多线程之实现单例模式的全部内容,希望文章能够帮你解决Java多线程之实现单例模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部