所有的锁都有性能消耗,高并发下,锁带来上下文切换,资源同步等消耗非常可观。,线程在锁上消耗比线程本身还多,应该尽可能少用锁,如果不可避免,那就用非阻塞算法解决问题,但不是绝对的。
内部锁:
java通过synchronized保持原子性,独占锁,锁请求互斥,跟高级锁(Lock/ReadWriteLock),synchronized简单,lock必须在finally代码里用,Lock的资源已经用到了极致,未来可优化空间不大,除非硬件有更高的性能。
性能
在高并发Web请求使用强制的独占锁,Web吞吐量会急剧下降。利用并发来提高性能,一个有效的出发点就是,更有效利用现有资源,让程序尽可能开阔可用资源,意味着机器尽可能忙碌,让cpu忙于计算而不是等待,更不是无谓的循坏。
线程阻塞
锁机制要操作系统支持,增加开销,锁竞争的时候,失败线程必然发生阻塞。JVM既能自旋等待,也能在操作系统中挂起组赛现场,直到超时或被唤醒,自旋适合并发短的等待,挂起线程适合耗时等待。挂起线程可能是因为无法获取锁,或者需要达到某个特定条件,或者耗时的I/O操作。比如,线程被挂起,拿到锁或者条件满足了,又要换回执行队列中,很耗时啊。
锁竞争
影响锁竞争因素
- 锁被请求频率
- 每次持有锁时间
二者小的话,无所谓,锁不当使用,开销很大。
减少锁竞争三种方式: - 减少锁持有时间
- 减少锁请求频率
- 采用共享锁取代独占锁
死锁
避免死锁方法,锁不用了就四方,高级lock用tryLock或者定时机制,时间到了没获取锁就放弃。
活锁
线程总是尝试某操作,却总失败,队列队头获取,每次都失败,放入队列,还是失败。