线程安全的单例模式
2015-08-06 10:01
274 查看
在我们项目中,很多时候需要程序只存在一个唯一实例。通常在项目中我会把单例模式写成如下形式
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
if (mSingleton == null) {
mSingleton = new Singleton();
}
return mSingleton;
}
}
通常以这种形式返回一个类的唯一实例,然而在Android开发中经常如果多线程开发。上面这种写法就不适合在多线程模式下运行了,会涉及到线程安全问题。因为很有可能两个线程同时会访问到getInstance()来创建实例。
因此我们使用线程同步来避免这一问题:
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (mSingleton == null) {
mSingleton = new Singleton();
}
}
return mSingleton;
}
}
如果多个线程访问时synchronized关键字,会一次只允许一个线程访问,其他线程先等待,恩,这确实避免了多线程同时访问带来的风险。那么又出现另一个问题,假如我项目复杂,线程多访问这个单例时一次只允许一个线程访问,其他线程等待,那性能上又存在很大的问题,每次实例时都得同步锁。
于是我们使用双从锁定,只在第一次类被实例化时判断 同步锁,解决线程安全,又解决效率问题
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
if (mSingleton == null) {
synchronized (Singleton.class) {
if (mSingleton == null) {
mSingleton = new Singleton();
}
}
}
return mSingleton;
}
}
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
if (mSingleton == null) {
mSingleton = new Singleton();
}
return mSingleton;
}
}
通常以这种形式返回一个类的唯一实例,然而在Android开发中经常如果多线程开发。上面这种写法就不适合在多线程模式下运行了,会涉及到线程安全问题。因为很有可能两个线程同时会访问到getInstance()来创建实例。
因此我们使用线程同步来避免这一问题:
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (mSingleton == null) {
mSingleton = new Singleton();
}
}
return mSingleton;
}
}
如果多个线程访问时synchronized关键字,会一次只允许一个线程访问,其他线程先等待,恩,这确实避免了多线程同时访问带来的风险。那么又出现另一个问题,假如我项目复杂,线程多访问这个单例时一次只允许一个线程访问,其他线程等待,那性能上又存在很大的问题,每次实例时都得同步锁。
于是我们使用双从锁定,只在第一次类被实例化时判断 同步锁,解决线程安全,又解决效率问题
public class Singleton {
private static Singleton mSingleton;
private Singleton() {
}
public static Singleton getInstance() {
if (mSingleton == null) {
synchronized (Singleton.class) {
if (mSingleton == null) {
mSingleton = new Singleton();
}
}
}
return mSingleton;
}
}
相关文章推荐
- 社説 20150806 米の盗聴疑惑 同盟の信頼関係を揺るがすな
- 南邮 OJ 1601 数次统计
- cleaning selected projects has encountered a problem errors occurred during build
- 链表的基本操作,包括创建,输出链表。
- hdu 1010 dfs+剪枝
- MFC窗口变化消息( OnSize、OnSizing和OnGetMinMaxInfo)
- python分析accesslog并排序
- 服务器IP变更后如果更新openfire 服务IP
- 实战篇:如何利用报表工具搭建机电行业综合管理平台
- Swift开发教程--如何通过定位来获取经纬度
- java中静态代码块的用法 static用法详解
- 日经社説 20150806 被爆70年に改めて核のない世界を誓う
- php瀑布示例
- 删除文件及文件夹
- 南邮 OJ 1599 统计
- iOS如何把导航默认的返回按钮设置成“返回”
- 蓝牙传输
- 消除临时对象
- 2015 HUAS Summer Trainning #4~C
- Evercookie 小结