单例模式-java实现

介绍

单例模式的意图:保证某个类在系统中有且仅有一个实例。

我们可以看到下面的类图:一般的单例的实现,是属性中保持着一个自己的私有静态实例引用,还有一个私有的构造方法,然后再开放一个静态的获取实例的方法给外界获取实例对象。

代码实现

在java中有两种实现的方法

  • 饿汉式:在类加载的时候就创建好实例
  • 懒汉式:在请求实例时才创建实例

饿汉式

在类加载的时候就创建好实例

java 复制代码
public class TestObj {
    private static TestObj testObj=new TestObj();
    //构造方法私有化
    private TestObj(){

    }
    //提供一个外界获取单实例的静态方法
    public static  TestObj getTestObj(){
        return testObj;
    }
}

懒汉式

由于java是多线程的,很有可能多个线程同时进入,导致创建多个实例,于是我们要使用锁机制来让线程之间互斥访问

java 复制代码
public class TestObj2 {
    //初始,维护一个静态的空引用
    private static TestObj2 testObj2=null;
    //私有的构造方法
    private TestObj2(){

    }
    //提供给外界获取单实例的静态方法
    public static TestObj2 getTestObj2(){
        //在这里,由于java是多线程的,很有可能多个线程同时进入,导致创建多个实例,于是我们要使用锁机制来让线程之间互斥访问
        //多线程同时判断,如果不为null,直接返回
        if (testObj2!=null){
            return testObj2;
        }
        //使用同步代码块进行线程互斥访问
        synchronized (Object.class){
            //其他线程进入以后,如果已经创建好了对象,则直接返回
            if (testObj2!=null){
                return testObj2;
            }
            else {
                //初始化单实例
                testObj2=new TestObj2();
            }

        }
        return testObj2;

    }
}

我们这里测试一下:

创建三个线程同时去获取实例,看输出的地址是否一样

java 复制代码
//创建一个runable接口
class DoTask implements Runnable{
    @Override
    public void run() {
        //获取实例对象并输出
        TestObj2 testObj2 = TestObj2.getTestObj2();
        System.out.println(testObj2);
    }
}

class Main{
    public static void main(String[] args) {
        Runnable runnable=new DoTask();
        //创建多个线程去获取实例
        Thread thread1=new Thread(runnable);
        Thread thread2=new Thread(runnable);
        Thread thread3=new Thread(runnable);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

运行结果:

可以看到输出的三个地址都是相同的,因此我们上面的懒汉式代码是完全可行的,这里仅仅讨论单服务器的情况,如果是分布式系统中的单实例,就要考虑使用分布式锁,或者redis,zookeeper等分布式协调工具去完成了

相关推荐
七牛开发者5 分钟前
Codex 实践系列 Vol.04:用 Goal 和 Plan 管住一个长任务
java·数据库·人工智能·github·copilot
我命由我1234511 分钟前
Android Drawable - gradient
android·java·java-ee·kotlin·android studio·android-studio·android runtime
clear sky .12 分钟前
[freertos源码阅读]task.c任务篇
c语言·开发语言
XR12345678833 分钟前
工业园区整体组网,方案对比怎么选?
开发语言·php
东东最爱敲键盘38 分钟前
day9.C++多态之虚函数
开发语言·c++
meilindehuzi_a41 分钟前
WebGPU DeepSeek项目实战(二):用单例模式加载Tokenizer并转发下载进度
单例模式·typescript·react
码云数智-园园1 小时前
类似小鹅通的知识付费小程序平台有哪些
开发语言
淡海水1 小时前
15-07-YooAsset面试篇-Unity性能优化与内存管理
java·unity·面试·性能优化·c#·游戏引擎
snow@li1 小时前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
Livia要学习1 小时前
Python闭包
开发语言·jvm·python