• 单例模式及其线程安全问题


    单例模式

    饿汉模式(饥渴,一开始就实例化对象)

    package java_study;
    
    public class HungerySingletonDemo {
    	//1.私有化构造器
    	private HungerySingletonDemo() {}
    	//2.实例化对象(饿汉)
    	private static HungerySingletonDemo instance = new HungerySingletonDemo();
    	//3.提供获取方法
    	public static HungerySingletonDemo getInstance() {
    		return instance;
    	}
    }
    

    懒汉模式(也叫懒加载)(直到被调用才实例化对象)

    package java_study;
    
    public class LazySingletonDemo {
    	// 1.私有化构造器
    	private LazySingletonDemo() {
    	}
    
    	// 2.声明对象(饿汉)
    	private static LazySingletonDemo instance = null;
    
    	// 3.提供获取方法并实例化,使用判断是否单例
    	public static LazySingletonDemo getInstance() {
    		if (instance == null) {
    			instance = new LazySingletonDemo();
    		}
    		return instance;
    	}
    }
    

    线程安全问题

    由于懒汉式存在多个线程调用同一个对象资源,存在线程不安全问题,需要使用同步机制来解决该问题
    饿汉模式不存在线程安全问题,在加载类的时候就实例化对象了

    同步方法

    // 3.提供获取方法并实例化,使用判断是否单例
    synchronized public static LazySingletonDemo getInstance() {
    	if (instance == null) {
    		instance = new LazySingletonDemo();
    	}
    	return instance;
    }
    

    能解决线程安全问题,但由于synchronized的作用域过大,应当使用双重检查加锁

    同步代码块(双重检查加锁)

    双重检查加锁,进入getInstance方法先不同步,先判断实例是否存在,如果不存在执行一次同步代码块,以后不再执行保证了安全性,又不会使性能受过大的影响

    // 2.声明对象(饿汉),使用volatile 该资源不会被本地线程缓存,资源直接共享内存,保证了多个线程能正确处理该资源
    private static volatile LazySingletonDemo instance = null;
    
    // 3.提供获取方法并实例化,使用判断是否单例
    public static LazySingletonDemo getInstance() {
    	if (instance == null) {
    		//多个线程有可能同时进入这个位置,仍然会创建多个实例,如果线程存在,以后都不会执行同步代码块了
    		synchronized (LazySingletonDemo.class) {//由于该方法是静态方法,同步锁是 类.class
    			//因此需要再次判断
    			if (instance == null) {
    				instance = new LazySingletonDemo();
    			}
    		}
    	}
    	return instance;
    }
    

    !推荐使用饿汉模式,简单粗暴

  • 相关阅读:
    Activity.startManagingCursor方法
    android SQLite使用SQLiteOpenHelper类对数据库进行操作
    Android类参考---SQLiteOpenHelper
    使用SQLiteOpenHelper类对数据库简单操作
    dom4j 最常用最简单的用法(转)
    setContentView()与LayoutInflater.inflate()作用
    Android listview与adapter用法
    ListView属性及divider设置分割线
    android布局属性详解
    Android layout属性之gravity和layout_gravity
  • 原文地址:https://www.cnblogs.com/cenzhongman/p/7305496.html
Copyright © 2020-2023  润新知