设计模式:单例模式
2016-03-08 10:43
316 查看
单例模式:确保一个类只有一个实例,并提供全局访问点。
通过私有化构造方法,我们可以使一个类不能在外部被实例化。
单这样实现当多线程的情况下会存在问题,如果多个线程同时
在
但是,这样同样存在一个问题,每一个进入这个方法都要同步,如果
放弃延迟实例化,在JVM加载该类的时候,我们就创建唯一的实例,这样任何线程访问都没问题。
这样写代码,大量减少了同步带来的性能消耗,又防止了多线程带来的问题。
通过私有化构造方法,我们可以使一个类不能在外部被实例化。
public class MyClass { private MyClass(){ System.out.println("private MyClass()"); } }
public class Main { public static void main(String[] args) { MyClass mc = new MyClass();//这里我们进行实例化的时候,编译器提示错误 } }
实现一
public class Singleton { private static Singleton instance; private Singleton(){ System.out.println("private Singleton()"); } public static Singleton getInstance(){ if(instance == null){ instance = new Singleton();//这里只有当我们需要的时候才会new(这就是延迟实例化,lazy instantiaze),如果不需要就会永远也不创建(这样相比全局变量而言,节约了资源),并且只会new一次。 } return instance; } }
单这样实现当多线程的情况下会存在问题,如果多个线程同时
getInstance,同时走到了
if(instance==null)这一步,那么这几个线程都将进入if,就创建了多个对象。这是我们不能容忍的。
实现二
public class Singleton { private static Singleton instance; private Singleton(){ System.out.println("private Singleton()"); } public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
在
getInstance方法上添加
synchronized关键字,这样就不存在多个线程同时进入该方法了。
但是,这样同样存在一个问题,每一个进入这个方法都要同步,如果
getInstance需要拼房的运行,这样就造成了一些性能浪费。
方法三
public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){ System.out.println("private Singleton()"); } public static Singleton getInstance(){ return instance; } }
放弃延迟实例化,在JVM加载该类的时候,我们就创建唯一的实例,这样任何线程访问都没问题。
方法四(双重检查加锁)
public class Singleton { private volatile static Singleton instance = null; private Singleton(){ System.out.println("private Singleton()"); } public static Singleton getInstance(){ if(instance == null){ synchronized(Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } }
这样写代码,大量减少了同步带来的性能消耗,又防止了多线程带来的问题。
volatile:用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。
相关文章推荐
- Python Singleton
- 各类算法技巧核心代码,知识点归纳总结之单调递增子序列
- MultipartFile 转 File
- Actionbarsherlock与Viewpagerindicator详解
- eclipse插件开发调试报错,出现内存溢出的情况
- Vim 配置和使用
- 重温设计模式一:类关系
- ubuntu 下androidsdk 更新
- ubuntu 除home目录,其他目录修改时权限的修改
- 公钥和私钥解释
- android apk 源码 的 破译(反编译)
- mybatis beanupdate报错
- archLinux ibus 中文 双拼音的安装
- archLinux VirtualBox增强设置
- C# -- 使用委托
- IE7 自动为文件路径添加域名
- destroy其他所有activity
- 替换Manifest.xml,界面替换(动态布局、动态获取R文件)
- Python实现单例类
- MySQL中外键设置详解