/**

  • 静态私有的成员变量持有Singleton对象的引用

*/

private static Singleton singleton;

/**

  • 私有构造函数,只有类的内部可以使用

*/

private Singleton() {

}

/**

  • 静态方法获取实例对象

*/

public static Singleton getInstance() {

if (singleton == null) {

singleton = new Singleton();

}

return singleton;

}

}

public void doSomething() {

}

public class Client {

public static void main(String[] args) {

Singleton instance = Singleton.getInstance();

instance.doSomething();

}

}

单例模式中的线程安全问题

在高并发多线程访问单例的情况下,上述代码是不安全的。为什么?假设第一个线程执行到getInstance()中的singleton = new Singleton()时,第二个线程也开始访问getInstance()方法,但是此时第一个线程要获取的实例对象还没完成,也就是说new Singleton()需要一定的时间,那么此时第二个线程访问判断singleton == null的条件还是成立的,那就会进行创建对象的过程。因此这时会出现创建了两个对象,两个线程访问的不是同一个对象,假如有若干线程同时访问,则产生对象的数量不唯一。

解决单例线程安全的方法:

1. 将访问方法变为同步方法(synchronized)

public class Singleton {

private static Singleton singleton;

private Singleton() {}

public static synchronized Singleton getInstance() {

if (singleton == null) {

singleton = new Singleton();

}

retu
rn singleton;

}

}

使用synchronized关键字可以避免多线程访问的安全问题,这是java语言的特性,synchronized使得一个线程在访问此方法时必须等待另一个线程离开该方法,相当于给方法加锁,但是这样也不是最佳的方式,因为一旦加了synchronized关键字就意味着在每次访问时都要进行同步操作,而同步是影响性能的,假如同步造成的性能影响对系统来说可以忽略,那么你可以不必在意。

2.使用饿汉单例模式

上述代码所示例的单例模式又称为懒汉单例模式,与之对应的还有一种就是饿汉单例模式,懒汉是将对象初始化延时处理,而饿汉则是在定义成员变量的时候直接初始化对象:

public class Singleton {

private static Singleton singleton = new Singleton();

private Singleton() {}

public static Singleton getInstance() {

return singleton;

}

}

这种方式是直接静态初始化一个实例对象,Java虚拟机JVM在加载类的时候就会创建该实例,这样就能保证在任何线程访问的时候该实例一定存在且唯一了。因为单例模式的目的就是确保存在一个唯一对象, 如果直接静态初始化带来的负担不是很大,可以考虑这种方式。但是如果new Singleton()需要的代价比较大,比如会占用极高的内存或者比较耗时,那么你需要慎重考虑了,因为假如实例对象并没有机会被访问到(假设你只用到了其中的静态方法),那么直接静态初始化了一个对象是不是浪费了资源呢。

饿汉和懒汉相比,还有一种极端的情况就是,假如对象长期未被使用,JVM是有可能回收掉该对象的,一旦被回收掉,懒汉模式下getInstance()会重新创建该对象,而饿汉模式下getInstance()则会直接返回null,但是这种情况现在基本不会存在,在java1.2以前会存在这个问题,后续的jdk版本中java修复了这个bug。

3.使用双重检查加锁减少同步次数(Double Check Lock)

为了减少同步的次数,我们可以将synchronized移到方法的内部,因为实际上一旦我们创建好了实例对象,实例对象已经存在的情况下,其它线程再来访问肯定是同一个对象。所以只需要在第一次访问的时候提供同步加锁就可以,第二次对象已存在就不需要再加锁了。

public class Singleton {

/*使用volatile保证对该变量的写入对另一个线程可见/

private volatile static Singleton mSingleton = null;

private Singleton(){}

public static Singleton getInstance() {

if (mSingleton == null) {

synchronized (Singleton.class) {

if (mSingleton == null) {

mSingleton = new Singleton();
te Singleton(){}

public static Singleton getInstance() {

if (mSingleton == null) {

synchronized (Singleton.class) {

if (mSingleton == null) {

mSingleton = new Singleton();

单例模式,androidstudio简易app实例相关推荐

  1. Launcher3 安装App加载显示过程分析,androidstudio开发app实例

    "Initializing LauncherAppState in the absence of LauncherProvider"); } Log.v(Launcher.TAG, ...

  2. tinker热修复gradle接入,androidstudio开发app实例

    tinkerPatch { /** necessary,default 'null' the old apk path, use to diff with the new apk to build a ...

  3. 分享一个Cnblogs简易APP

    最近在学习Android app的开发,俗话说万事开头难,本人也不例外.计算机编程是属于一门要求动手能力和动脑能力都很强的学科,相信很多人都会有这样的经历,看得懂不去用,过不了几天也就忘记了.因而,在 ...

  4. AndroidStudio Launching ‘app‘ Time out 错误

    问题一 AndroidStudio Launching 'app' Time out 错误 环境: AndroidStudio: Arctic Fox 2020.3.1 问题 点击debugger运行 ...

  5. 【Android应用开发之前端——简易App登录页面】

    1.完成登录页面布局 各家App的登录页面大同小异,要么是用户名和密码组合登录,要么是手机号和验证码组合登录.如果要做的更好一点,就要提供忘记密码与记住密码等功能.我们的App登录项目把这些功能综合一 ...

  6. 微信小程序自定义组件中获取app实例的值,生命周期与页面的生命周期执行先后顺序

    调试基本库:2.12.2 最近在接触微信小程序开发 有这么一个需求,自定义组件需要给页面传一个app实例的参数, 总结: 1.自定义组件中data 不能直接获取app.globalData 2.通过自 ...

  7. Java单例模式个人总结(实例变量和类变量)

    Java单例模式 背景知识:Static关键字. 在对于定义类的变量,分为两种,是否具有static修饰的变量: 没有static修饰的变量,通过类的实例化(对象)引用,改变量称为实例变量: 使用st ...

  8. java 工厂 单例_java 单例模式和工厂模式实例详解

    单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例. 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 饿汉式单例 public class ...

  9. android简单app实例_Android安卓小项目实战视频教程集锦

    Android安卓小项目实战视频教程,点击进入视频教程: 一.安卓项目视频教程: 1蓝牙聊天APP介绍-分步骤介绍一个简单安卓蓝牙APP的开发过程 - 西瓜视频 2蓝牙聊天开发流程-分步骤介绍一个简单 ...

  10. Android中应用百度地图API开发地图APP实例-显示百度地图

    场景 效果 在使用百度地图API之前需要先在百度地图开放平台中申请API_KEY http://lbsyun.baidu.com/index.php 申请API_KEY 登录百度开放平台后找到控制台下 ...

最新文章

  1. 【怎样写代码】确保对象的唯一性 -- 单例模式(四):饿汉式单例类与懒汉式单例类的讨论
  2. MySQL5.7 解决 字符编码问题 与 安装完 MySQL 无 my.ini
  3. Microsoft Dynamics CRM server 2013 一般销售流程之 报价单功能详解
  4. STM32的USART发送数据时如何使用TXE和TC标志
  5. 项目设计基础:处理过程设计相关知识介绍​
  6. 能量采集(HYSBZ-2005)
  7. html音乐播放器代码自动,html5 css3音乐播放器代码
  8. Flutter 随机颜色 颜色处理工具类
  9. sql2008 服务器未响应,sql配置管理器,SQL server (MSSQLSERVER)开启不了,请求失败或服务器未响应....
  10. 无法运行的愿意_旧电脑的福音:Win10精简版,运行比Win7更快,安装包不到3GB
  11. (转)ORACLE之常用FAQ V1.08
  12. iview table增加一行减少一行_OA协会领导一行赴深圳市办公设备租赁行业协会参观交流...
  13. subli快速度创建html,JS插件——自定义下拉框
  14. 年会互动游戏有哪些?年会微信互动游戏制作流程是什么?
  15. 一些常见的Common类
  16. Liunx 切换用户This account is currently not available
  17. win7下计算机假死,造成Windows7系统假死的原因及处理方法
  18. 初级算法-10. 有效的数独
  19. iOS开发-将UIView置于最上层
  20. NOI 雇佣兵讲解(c/c++)

热门文章

  1. 电商商家如何利用商品信息制定价格策略?
  2. JAVA计算机毕业设计新闻推送系统Mybatis+源码+数据库+lw文档+系统+调试部署
  3. Python 模块—计算三角形的斜边长
  4. 苹果鼠标怎么充电_macbook pro搭配什么鼠标好?
  5. 注册Heroku账户
  6. 命令执行专题总结突破
  7. 阿里巴巴29个屌炸天的开源项目!
  8. 太极图形html5代码,HTML5 Canvas组件绘制太极图案
  9. 计算机网络原理笔记精整理(汇总)
  10. 11讲项目实战首页右侧悬浮框及内页面包屑导航