Go和Java实现单例模式

这篇具有很好参考价值的文章主要介绍了Go和Java实现单例模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go和Java实现单例模式

1、单例模式

单例模式是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问

其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供

这一实例。

  • 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 主要解决:一个全局使用的类频繁地创建与销毁。

  • 何时使用:当您想控制实例数目,节省系统资源的时候。

  • 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

  • 关键代码:构造函数是私有的。

  • 应用实例:

    1、一个班级只有一个班主任。

    2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文

    件的现象,所以所有文件的处理必须通过唯一的实例来进行。

    3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印

    机打印同一个文件。

  • 优点:

    1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓

    存)。

    2、避免对资源的多重占用(比如写文件操作)。

  • 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例

    化。

  • 使用场景:

    1、要求生产唯一序列号。

    2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

    3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

  • 注意事项:getInstance() 方法中需要使用同步锁防止多线程同时进入造成 instance 被多次实例化。

  • 适用性:

    当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

    当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

2、Go实现单例模式

单例模式分为饿汉式和懒汉式:

  • 饿汉式:在该类初始化的时候就创建实例对象,线程是安全的。

  • 懒汉式:首次使用单例实例的时候创建,之后使用时再判断单例实例是否已创建,如果没有则创建实例。

单例模式采用了饿汉式和懒汉式两种实现,饿汉式的实现简单并且可以将问题及早暴露,懒汉式虽然支持延迟载,

但是这只是把冷启动时间放到了第一次使用的时候,并没有本质上解决问题,并且为了实现懒汉式还不可避免的需

要加锁。

2.1 饿汉式

package main

import "fmt"

type EagerSingleton struct {
}

var eagerSingletonObj *EagerSingleton

func init() {
	eagerSingletonObj = &EagerSingleton{}
}

func GetInstance() *EagerSingleton {
	return eagerSingletonObj
}

func main() {
	// true
	fmt.Println(GetInstance() == GetInstance())
}

2.2 懒汉式

package main

import (
	"fmt"
	"sync"
)

type LazySingleton struct {
}

var (
	lazySingletonInstance *LazySingleton
	lazyOnce              = &sync.Once{}
)

func GetLazySingletonInstance() *LazySingleton {
	if lazySingletonInstance == nil {
		lazyOnce.Do(func() {
			lazySingletonInstance = &LazySingleton{}
		})
	}
	return lazySingletonInstance
}

func main() {
	// true
	fmt.Println(GetLazySingletonInstance() == GetLazySingletonInstance())
}

2.3 双检锁

package main

import (
	"fmt"
	"sync"
)

type DoubleCheckSingleton struct {
}

var lock = &sync.Mutex{}

var doubleCheckSingletonInstance *DoubleCheckSingleton

func GetDoubleCheckSingletonInstance() *DoubleCheckSingleton {
	if doubleCheckSingletonInstance == nil {
		lock.Lock()
		defer lock.Unlock()
		if doubleCheckSingletonInstance == nil {
			doubleCheckSingletonInstance = &DoubleCheckSingleton{}
		}
	}
	return doubleCheckSingletonInstance
}

func main() {
	// true
	fmt.Println(GetDoubleCheckSingletonInstance() == GetDoubleCheckSingletonInstance())
}

3、Java实现单例模式

Java 实现单例模式总共有 5 中方法。

下面的几种方式都是线程安全的。

3.1 饿汉式

饿汉式线程安全,调用效率高,但是不能延时加载。

package com.singleton;

public class Singleton1 {

    private static Singleton1 instance = new Singleton1();

    private Singleton1() {
    }

    public static Singleton1 getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        Singleton1 a1 = Singleton1.getInstance();
        Singleton1 a2 = Singleton1.getInstance();
        // true
        System.out.println(a1 == a2);
    }
}

3.2 懒汉式

懒汉式线程不安全,调用效率不高,但是能延时加载。

懒汉式本身是线程不安全的,这里添加了 synchronize,所以是线程安全的。

package com.singleton;

public class Singleton2 {

    private static Singleton2 instance;

    private Singleton2() {
    }

    public static synchronized Singleton2 getInstance() {
        if (instance == null) {
            instance = new Singleton2();
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton2 a1 = Singleton2.getInstance();
        Singleton2 a2 = Singleton2.getInstance();
        // true
        System.out.println(a1 == a2);
    }
}

3.3 双检锁

双检锁也就是双重锁判断机制。

package com.singleton;

public class Singleton3 {

    private volatile static Singleton3 instance;

    private Singleton3() {
    }

    public static Singleton3 getInstance() {
        if (instance == null) {
            synchronized (Singleton3.class) {
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton3 a1 = Singleton3.getInstance();
        Singleton3 a2 = Singleton3.getInstance();
        // true
        System.out.println(a1 == a2);
    }
}

3.4 静态内部类实现模式

线程安全,调用效率高,可以延时加载。

package com.singleton;

public class Singleton4 {

    private static class SingletonClassInstance {
        private static final Singleton4 instance = new Singleton4();
    }

    private Singleton4() {
    }

    public static Singleton4 getInstance() {
        return SingletonClassInstance.instance;
    }

    public static void main(String[] args) {
        Singleton4 a1 = Singleton4.getInstance();
        Singleton4 a2 = Singleton4.getInstance();
        // true
        System.out.println(a1 == a2);
    }
}

3.5 枚举类

线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用。

package com.singleton;

public enum Singleton5 {
    // 枚举元素本身就是单例
    INSTANCE;

    // 添加自己需要的操作
    public void singletonOperation() {
        System.out.println("Operation!");
    }
}
package com.singleton;

public class Test {
    public static void main(String[] args) {
        Singleton5 singletonA = Singleton5.INSTANCE;
        Singleton5 singletonB = Singleton5.INSTANCE;
        // true
        System.out.println(singletonA == singletonB);
        // Operation!
        singletonA.singletonOperation();
        // Operation!
        singletonB.singletonOperation();
    }
}

3.6 使用CAS

package com.singleton;

import java.util.concurrent.atomic.AtomicReference;

public class Singleton6 {

    private static final AtomicReference<Singleton6> INSTANCE = new AtomicReference<>();

    private Singleton6() {
    }

    public static final Singleton6 getInstance() {
        while (true) {
            Singleton6 instance = INSTANCE.get();
            if (null != instance) {
                return instance;
            } else {
                INSTANCE.compareAndSet(null, new Singleton6());
                return INSTANCE.get();
            }
        }
    }

    public static void main(String[] args) {
        // true
        System.out.println(Singleton6.getInstance() == Singleton6.getInstance());
    }
}
  • java 并发库提供了很多原⼦类来⽀持并发访问的数据安全性:

    AtomicInteger 、 AtomicBoolean 、 AtomicLong 、 AtomicReference

  • AtomicReference 可以封装引⽤⼀个 V 实例,⽀持并发访问如上的单例⽅式就是使⽤了这样的⼀个特点。

  • 使⽤ CAS 的好处就是不需要使⽤传统的加锁⽅式保证线程安全,而是是依赖于 CAS 的忙等算法,依赖于底层

    硬件的实现,来保证线程安全。相对于其他锁的实现没有线程的切换和阻塞也就没有了额外的开销,并且可以

    ⽀持较⼤的并发性。

  • 当然 CAS 也有⼀个缺点就是忙等,如果⼀直没有获取到将会处于死循环中。文章来源地址https://www.toymoban.com/news/detail-704912.html

到了这里,关于Go和Java实现单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA设计模式——单例模式

    单例模式是应用最广的设计模式之一,也是程序员最熟悉的一个设计模式,使用单例模式的类必须保证只能有创建一个对象。 今天主要是回顾一下单例模式,主要是想搞懂以下几个问题 为什么要使用单例? 如何实现一个单例? 单例存在哪些问题? 单例对象的作用域的范围

    2024年02月16日
    浏览(41)
  • 【java】设计模式——单例模式

    单例模式要点 : 一个类只需要一个实例化对象; 必须自行创建实例; 必须自行向整个系统提供这个实例 实现 : 只提供 私有 构造方法; 有一个该类的 静态 私有对象; 提供一个静态 公有 方法用于创建、获取静态私有对象; 分析: 私有构造方法-不能随意创建实例; 静态

    2024年02月13日
    浏览(43)
  • Java设计模式-单例模式

    单例模式是一种设计模式,它确保一个类只能创建一个实例,并提供一种全局访问这个实例的方式。在Java中,单例模式可以通过多种方式来实现,其中最常见的是使用私有构造函数和静态方法实现 在Java中,实现单例模式的方式有多种,其中最常见的实现方式包括以下几种:

    2024年02月01日
    浏览(42)
  • java设计模式-单例

    单例模式是一种创建型设计模式,它可以保证一个类只有一个实例,并提供全局访问点。单例模式在实际开发中经常使用,可以避免多个实例引起的资源浪费和同步问题。常见的java实现方式有多种。 饿汉式单例模式是指在类加载时就创建了单例对象,因此在调用时不需要再

    2024年01月18日
    浏览(51)
  • Java设计模式---单例 工厂 代理模式

    单例模式是设计模式中的一种,属于创建型模式。在软件工程中,单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于那些需要频繁实例化然后引用,且创建新实例的开销较大的类,例如数据库连接池、缓存管理等。 意图 :保证一个类仅有一个实例

    2024年01月24日
    浏览(50)
  • 设计模式篇(Java):单例模式

    上一篇:设计模式篇(Java):前言(UML类图、七大原则) 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 构造器私有化 (防止 new ) 类的内部创建对象 向外暴露一个静

    2024年02月11日
    浏览(58)
  • Java——单例设计模式

    设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱、“套路”。 经典的设计模式共有23种。每个设计模式均是特定环境下特定问题的

    2024年02月11日
    浏览(45)
  • 【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

    🍎 个人博客: 个人主页 🏆 个人专栏: JAVA ⛳️   功不唐捐,玉汝于成 目录 前言 正文 懒汉式(Lazy Initialization): 双重检查锁定(Double-Checked Locking): 结语 我的其他博客 在软件设计中,单例设计模式是一种重要的设计思想,它确保了一个类只有一个实例,并提供了一

    2024年01月15日
    浏览(51)
  • Java设计模式(八)— 单例模式3

    单例模式之静态内部类 单例模式之枚举方式 单例模式之JDK源码分析 Hello,小伙伴们,欢迎来到柚子的博客~让我们一起成长吧o( ̄▽ ̄)ブ 提示:以下是本篇文章正文内容,下面案例可供参考 代码如下(示例): 类被装载的时候,类里面的静态内部类也是会被装载的,而且线

    2024年02月09日
    浏览(64)
  • Java与设计模式(4):单例模式

    单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点来访问该实例。 在单例模式中,类的构造函数被私有化,从而禁止外部直接实例化该类。通过一个静态方法或静态变量来控制类的实例化过程,并返回同一个实例。 单例模式的特点包括: 单一

    2024年02月12日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包