锁为什么耗性能:

 1. 每个线程在被cpu执行的时候, 都会给这个线程分配一定的时间让这个线程执行, 这段时间不会被信号中断.

 2. 在获取锁的时候, 如果竞争很激烈, 这个线程会被挂起, 所以, 如果获取锁的操作很多, 这个线程就会频繁被挂起, 无法利用完cpu分配给它的时间, 时间都浪费

在了contextSwitch 上, 所以说, 获取锁是比较费时的操作

3. contextSwith 的耗时大概是5,000 to 10,000 clock cycles or several microseconds on most current processors.

The  vmstat   command  on  Unix  systems  and  the  perfmon   tool  on  Windows  systems  report  the  number  of  context
switches and the percentage of time spent in the kernel. High kernel usage (over 10%) often indicates heavy scheduling
activity, which may be caused by blocking due to I/O or lock contention.

用top也可以

锁的消耗也分竞争激烈的锁和竞争不激烈的锁, 竞争不激烈的锁消耗会比较小. 竞争太激烈的话, 会导致很多线程会被os挂里, 有相应的contextSwitch 的操作, cache miss的操作, os的算法,对os的通知等等 所以竞争激烈不激烈也比较重要

There are three ways to reduce lock contention:
• Reduce the duration for which locks are held;
• Reduce the frequency with which locks are requested; or
• Replace exclusive locks with coordination mechanisms that permit greater concurrency.

 

Lock  splitting  and  lock  striping  can  improve  scalability  because  they  enable  different  threads  to  operate  on  different
data  (or  different  portions  of  the  same  data  structure)  without  interfering  with  each  other.

锁的splitting是指,相互独立的变量使用不同的锁. striping是指一个变量的不同部分的数据使用不同的锁.

如果说有俩个变量,使用了同一个锁, 而且锁的竞争非常的激烈,使用splitting的性能提升也许不是很好,因为这意味这进行了splitting后,俩个锁的竞争还是很激烈,一次只有俩个线程可以同时进行. 只有当这个锁的竞争处于中等的竞争强度的时候,进行splitting的性能提升会很好

在进行锁的splitting和striping的时候, 要确定锁的竞争确实比较激烈

避免热点, 热点的产生,一个原因是有一个变量,所有的操作都需要用到它.然后它就成了热点 concurrentHashMap 解决size的热点问题,通过在不同的strips都维护自己的size,需要的时候,把他们都加起来

其他的减弱热点的方法是:放弃使用排它锁,使用concurrrentCollections,read-write lock,immutable state,atomatic variables 等等

or  read‐mostly  data  structures,  ReadWriteLock   can  offer  greater  concurrency  than  exclusive  locking;  for
read‐only data structures, immutability can eliminate the need for locking entirely.

Atomic variables (see Chapter 15) offer a means of reducing the cost of updating "hot fields" such as statistics counters,
sequence generators, or the reference to the first node in a linked data structure. (We used  AtomicLong  to maintain the
hit counter in the servlet examples in Chapter 2.) The atomic variable classes provide very fine‐grained (and therefore
more  scalable)  atomic  operations  on  integers  or  object  references,  and  are implemented  using  low‐level  concurrency
primitives  (such as compare‐and‐swap)  provided by  most modern processors

一般来说, fair的锁的性能要比unFair的锁的性能要好很多: 比如, A线程正在持有锁,B线程获取不到锁被挂起了,然后A线程释放锁,这是B线程被唤醒,这时,C线程来获取锁,在unfair的情况下,C会更快的获取到锁,也许c执行完后,b刚好唤醒完毕,然后b也拿到锁进行操作. 这样的话,就比等到b唤醒后拿到锁执行完,然后c再唤醒拿锁执行 这种吞吐量

要多.  如果线程持有锁的时间很长,或者竞争很少的话,fair的锁的吞吐量还是可以的. intrisic的锁就是一种unfair的锁