单例模式

本文详细介绍了单例模式的实现方式,包括普通写法、静态内部类写法及Android中的使用方式,并探讨了不同方式下的优缺点,特别是针对并发环境下如何避免多实例的产生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、单例模式: copy

1.静态实例,带有static关键字的属性在每一个类中都是唯一的。

2.限制客户端随意创造实例,即私有化构造方法,此为保证单例的最重要的一步。

3.给一个公共的获取实例的静态方法,注意,是静态的方法,因为这个方法是在我们未获取到实例的时候就要提供给客户端调用的,所以如果是非静态的话,那就变成一个矛盾体了,因为非静态的方法必须要拥有实例才可以调用。

4.判断只有持有的静态实例为null时才调用构造方法创造一个实例,否则就直接返回。

1、普通写法

public class Singleton {
private static Singleton instance;  //唯一一个实例
private Singleton() { }
public static Singleton getInstance() {
 if(instance==null)
   Thread.yield();            //创造多个实例的条件:第一个线程走到这让步,第二个线程走到这,就可能创造多个实例
  instance = new Singleton();
  return instance;
 }
}

但是这种方式有一个问题,为了快速模拟结果,我们加了Thread.yield();
代码:

public class SingletonLearn {

    public static void main(String[] args) throws InterruptedException {
        final Set<String> instanceSet = Collections.synchronizedSet(new HashSet<String>());
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10000; i++) {
            executorService.execute(new Runnable() {

                public void run() {
                    Singleton singleton = Singleton.getInstance();
                    instanceSet.add(singleton.toString());
                }
            });
        }
        TimeUnit.SECONDS.sleep(10);
        System.out.println("------并发情况下我们取到的实例------");
        for (String instance : instanceSet) {
            System.out.println(instance);
        }
        executorService.shutdownNow();
    }
}

这里写图片描述
从结果可以看到,创建了多个实例
找了下源码发现用的是这种的

package android.util;

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

我觉得还是按照源码来吧

2、在Android Studio创建的是这种方式

public class Singleton {
private static Singleton ourInstance = new Singleton();

public static Singleton getInstance() {
    return ourInstance;
}

private Singleton() {
} }

   接着抄一句:  上述方式与我们最后一种给出的方式类似,只不过没有经过内部类处理,这种方式最主要的缺点就是一旦我访问了Singleton的任何其他的静态域,就会造成实例的初始化,而事实是可能我们从始至终就没有使用这个实例,造成内存的浪费。
          不过在有些时候,直接初始化单例的实例也无伤大雅,对项目几乎没什么影响,比如我们在应用启动时就需要加载的配置文件等,就可以采取这种方式去保证单例。

3、 Android中的使用
在Android开发过程中内存泄漏的问题,所以要更新一种方式,看到资料的意思是,Singleton 是一个单例模式,这个类的生命周期就是application,创建时就持有了activity或其他类的引用,当系统回收时候,发现它仍然在内存中被Instance引用,所以GC回收失败,从而导致内存泄漏

public class WindowMnagerUtil {
    private static WindowMnagerUtil mWindowInstance;
    private Context context;

    private WindowMnagerUtil(Context context) {
        this.context = context.getApplicationContext();//这样单利模式的生命周期和应用一样了
    }

    public static WindowMnagerUtil getWindowInstance(Context context) {
        if (mWindowInstance == null)
            mWindowInstance = new WindowMnagerUtil(context);
        return mWindowInstance;
    }

    public void createWindow(Context context) {

    }
}

reference :
http://blog.youkuaiyun.com/u010687392/article/details/49909477

http://www.cnblogs.com/zuoxiaolong/p/pattern2.html

内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值