一、单例模式定义:
synchronized是用来控制线程同步的,在多线程的情况下保证代码不被同时执行
二,如何实现单列模式呢?
synchronized (同步锁(lock))
首先我们先讲解下几种synchronized 的用法,给一张图
上面的图写的很仔细
如果你想更加了解同步锁,可以看下这边博客让你彻底理解Synchronized - 简书
三,下面进入实战
android中如何使用同步锁呢?其实和java中一样
1. 饿汉式单例
public class BaseModel extends AppRetrofit {
private static final BaseModel baseModel = new BaseModel() ; //饿汉式单列首先创造出对象的实列
private BaseModel() { //将构造方法私有化,避免外部调用
}
public static BaseModel getInstance (){ //让外部调用的方法,获取实列
return baseModel;
}
优缺点: 首先饿汉式的优点是绝不会发生线程堵塞和创建多个对象的发生,缺点是类一加载就创建出来了,如果没有使用容易造成内存的浪费
2.懒汉式单列
public class BaseModel extends AppRetrofit {
private static BaseModel baseModel;
private BaseModel() { //将构造方法私有化,避免外部调用
}
public static BaseModel getIntance() {
synchronized (BaseModel.class) {
if (baseModel == null) { //加个判断不然容易造成创建多个对象
baseModel = new BaseModel();
}
return baseModel;
}
}
其实上面的等同于
public static synchronized BaseModel getIntance() {
if (baseModel == null) {
baseModel = new BaseModel();
}
return baseModel;
}
这样看大家就不容易误解了,哈哈,(注意:要是没有static的话就不一样了)
懒汉式的优化
private static BaseModel baseModel;
private BaseModel() { //将构造方法私有化,避免外部调用
}
public static BaseModel getIntance() {
if (baseModel == null){ //避免代码进入代码块的的浪费
synchronized (BaseModel.class) {
if (baseModel == null) {
baseModel = new BaseModel();
}
}
}
return baseModel;
}
3.静态内部类实现单例
public class DogBean {
private static DogBean dogBean;
private DogBean() {
}
static class inlinDogBean{
private static DogBean instace = new DogBean();
}
public DogBean getInstance(){
return inlinDogBean.instace;
}
}
根据jvm的加载机制,类加载时inlinDogBean不会被加载,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。因为没有用到锁的机制,所有不会损坏性能。
优化点在哪里呢
这个容易面试,大家可以记下,解释在上面,所以在进入的时候加一个判断,避免浪费,
补充一点 synchronized(this) 和 synchronized(.class)有什么区别呢?
1、一个是对象锁一个是类锁;
2、只要采用类锁,就会拦截所有线程,只能让一个线程访问。
3、对于对象锁(this),如果是同一个实例,就会按顺序访问,但是如果是不同实例,就可以同时访问。
4、如果对象锁跟访问的对象没有关系,那么就会都同时访问。