# Eventbus 笔记
## EventBus是什么eventbus是一个基于观察者模式的事件发布订阅框架,开发者可以通过极少的代码去实现多个模块之间的通信,而不需要以层层传递接口的形式去单独构建通信桥梁。从而降低因多重回调导致的模块间强耦合,同时避免产生大量内部类。它拥有使用方便,性能高,接入成本低和支持多线程的优点
## 1 注解- Documented 作用是能够将注解中的元素包含到javadoc中去- - Target 指定注解运用的地方 比如 ElementType.METHOD 这样就是作用在方法上面- - Retention 注解的存活时间,RetentionPolicy.RUNTIME注解可以保留到程序运行的时候,它会被加载进入到jvm中,所以在程序运行时可以获取到它们
## 2 synchronized 和ReentrantLock- synchronized(this) 和 synchronized method 只能防止多个线程同时执行同一个对象的同步代码- synchronized 锁住的是括号里面的对象,而不是代码。对于非static的 synchronized方法,锁的就是对象本身也就是this, 即使两个不同的代码段,都要锁同一个对象,那么这两个代码段也不能在多线程环境下同时运行。- 所以我们在用synchronized关键字的时候,尽量缩小代码段的范围,能在代码段加同步就不要再整个方法上加同步,这叫减小锁的粒度,使代码更大程度的并发。lock是一个接口 synchronizeds是Java中的关键字,synchronized是内置的语法.synchronzied在发送异常时,会自动释法线程占有的的锁,因此不会导致死锁现象发生;而lock在发生异常时,如果没有主动通过unlock去释放锁,则很有可能造成死锁现象,因此使用lock时需要在finally快中释放锁- - synchronized是非公平锁 它无法保证等待的线程获取锁的顺序 reentrantLock可以设置成公平锁
## 3 反射- getMethods() 获取该类的所有的public方法包括父类的- getDeclaredMethods() 获取该类的所有权限的方法,不包括父类的- getInterfaces() 获取该类实现的接口- invoke(...) 第一个参数是要调用这个方法的对象 第二个是该方法的参数
## 4 异或运算
## 5 hashMap - put 如果没值 返回null ,如果有值返回value
## 6 isAssignableFrom- Class?clazz = FindState.class;Object.class.isAssignableFrom(clazz) 调用者是否与被调用者是同样或者是他的超类超接口
## 7 volatile - 属性(这个很重要)在访问volatile变量时不会执行加锁操作,因此也就不会使用执行线程阻塞,因此volatile变量时一种比synchronized关键字更轻量级的同步机制
## 8 CopyOnWriteArrayList- CopyOnWrite容器 当往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素后,再将原容器的引用指向新的容器。这样做的好处 是我们可以对copyonwrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以copyOnWrite容器也是一种读写分离的思想,读和写不同的容器.从源码可以看到,add的时候是要加锁的,而get的时候不需要加锁,所以适用于读多写少的并发场景。
## 9 final class - 当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法
## 10 并发编程三大概念 原子性 有序性 可见性
#### 原子性:- 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何元素打断,要么就都不执行。只有简单的读取,赋值(而且必须将数字赋值给某个变量,变量之间的相互赋值不是原子操作) 才是原子操作.Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和lock来实现,由于sychronized和lock能够保证任一时刻只有一个线程执行该代码块,那么自然就不存在原子性问题了,从而保证了原子性
#### 可见性: - 当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值 - 而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线 程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。另外,通过synchronized和lock也能够保证可见性,synchronized和lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中,因此可以保证可见性。
#### 有序性:- 指令重排序,happens-before原则(先行发生原则)
## 11 享元设计模式
## 12 Executors- Executors是一个工厂类newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程- - newScheduledThreadPool创建一个定长线程池,支持定时及周期性任何执行。- newSingeThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所以任务按照指定顺序(FIFO,LIFO,youx)
## 13 String,StringBuffer和StringBuilder的区别- String是一个字符串类,是一个final类。是不可变的- StringBuffer本质是一个线程安全的可修改字符序列,它保证类线程安全,也随之带来了额外的性能开销,所以除非有线程安全的需求,不然还是推荐使用StringBuilder,- StringBuilder是1.5中新增的,在能力上和StringBuffer没有本质区别,但是它去掉了线程安全的部分,有效减小了开销,是绝大部分情况下进行字符串拼接的首选
## 14 EventBusAnnotationProcessor(EventBus注解分析生成索引)在编译阶段就把声明来subscribe注解的类和方法找到,并且放到subscriberInfoIndexes里面## 15 APT(Annotation Processing Tool) 可以在代码编译器解析注解,并且生成新的Java文件,减少手动代码输入。
## 16 ProGuard
代码混淆
## 17 for循环```List list = new ArrayList<>();
## 18 ThreadLocal
threadlocal是线程的局部变量,是每一个线程所单独持有的,其他线程不能呢对其进行访问,通常是类中的private static字段,是对该字段初始化的一个拷贝,她们希望将状态与某一个线程相关联
initialValue 返回泛形的对象
总结:eventbus是一个订阅发布的总线,它的实现原理大概
通过getdefault去register对象,register这个方法里面传入注册对象,通过这个注册对象的class去找到这个类里面的申明类
subscriber的方法,这个方法怎么找呢,如果是使用了eventbusannotationprocessor的话,在编译的时候就生成好了eventindex eventbus初始化的时候就先添加进去,register的时候就直接在缓存里面找到,如果没有使用这个的注解索引的话,就通过反射来找到对应的方法,在发送消息的地方使用post来发送,具体实现是在post哪里根据传进来的event 去找到对应的订阅者和声明来subscriber的方法,然后通过invoke方法来回调,它里面支持了不同的线程做了相应的处理