一、ReetrantLock
1. ReetrantLock基于内部类FairSync(公平锁)和NonFairSync(非公平锁)实现。可重入性是基于Thread.currentThread()实现。
2. 公平和非公平锁的队列都基于锁内部维护的一个双向链表,表结点Node的值就是每一个请求当前锁的线程。公平锁则在于每次都是依次从队首取值。
3. 公平锁和非公平锁都是排他锁。(注:共享锁(读锁),事务A给数据加了共享锁后,其它事务只可以再加共享锁,不能加排他锁;排他锁(写锁))
4. ReentrantLock 的公平锁和非公平锁都委托了AbstractQueuedSynchronizer#acquire去请求获取。
5. ReentrantLock 对线程的阻塞是基于 LockSupport.park(this); (见 AbstractQueuedSynchronizer#parkAndCheckInterrupt)。 先决条件是当前节点有限次尝试获取锁失败。
6. state使用volatile修饰
二、ReetrantReadWriteLock
1. ReadLock和WriteLock两个实现Lock接口的内部类
2. 构造方法默认非公平,可以传入参数创建公平的
3. sync 继承自AQS,sync有两个内部类HoldCounter(读锁)和ThreadLocalHoldCounter, ThreadLocalCounter重写了ThreadLocalCounter的initialValue
三、Condition
1. Lock.newCondition()获取Condition对象,condition.await,condition.signal,condition.signalAll()。
2. sync的内部类ConditionObject实现了condition接口。
四、@transactional
1. 可以用类似"propagation=REQUIRED"这种方式自定义传播机制,总共7种,默认为required,也就是使用已有的事务,没有就新建一个事务。
2. 事务失效的情况
- 未启用spring事务管理功能@EnableTransactionManagement
- 方法不是public类型的
- 数据源未配置事务管理器
- 自身调用问题
- 异常类型错误
- 异常被吞了
- 业务和spring事务代码必须在一个线程中
3. 事务的原理
spring是通过aop的方式,对需要spring管理事务的bean生成了代理对象,然后通过代理对象拦截了目标方法的执行,在方法前后添加了事务的功能,
所以必须通过代理对象调用目标方法的时候,事务才会起效。
五、索引
1) 失效的情况
1.有or必全有索引;
2.复合索引未用左列字段;
3.like以%开头;
4.需要类型转换;
5.where中索引列有运算;
6.where中索引列使用了函数;
7.如果mysql觉得全表扫描更快时(数据少)
2)没必要加索引的情况
1.唯一性差;
2.频繁更新的字段不用(更新索引消耗);
3.where中不用的字段;
4.索引使用<>时,效果一般;
六、redis
1. 哨兵模式,最少三台机器:Master、Slave、Sentinel
2. 集群模式16384个槽点
3. 为什么快:基于内存、非阻塞多路IO、单线程、乐观锁、专门设计的数据结构、底层模型vm机制、优秀的过期策略
4. Redis并没有使用C语言的字符串,而是使用了简单动态字符串(SDS)。相对于C语言的字符串来讲,SDS记录了自身使用和未使用的长度,
时间复杂度为O(1),而C语言则要遍历整个空间,时间复杂度为O(N)
5. Redis的链表为双端链表,链表节点带有perv和next指针,链表还带有head和tail指针,使得获取链表某节点前后置节点的时间复杂度都是O(1)。
并且Redis链表无环,prev和next指针指向null,对链表的访问以null作为截至的判断条件。
链表中有记录自身长度的属性len,并且链表使用void*
指针来保存节点值,可以通过list 结构的dup、free、match三个属性为节点值设置类型特定函数,
所以链表可以用来保存各种不同类型的值。