图解 --乐观锁 悲观锁 可重入锁 独占锁 共享锁 公平锁 非公平锁

1.乐观锁--乐观锁是一种思想,它只解决对共享资源更新时的一致性问题,不解决读取共享资源过程中,其他线程修改了共享资源导致读取的是旧的资源的问题

一般范式为:

private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

 

for(;;){
    更新期望共享资源;
    if(期望共享资源==现实共享资源){
    update();
    return
    }
}    

 

这种实现存在如下问题1):ABA问题----假如是链表结构,1线程操作期间,其他线程修改了A.next,1线程比较后自然以为是预期值,判断true,继续操作(解决办法加入版本号标识,比较的不仅仅是A的值还有A的版本号)

          2):自旋导致cpu压力

2.悲观锁--总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。应用场景可以抽象成如下图

可重入锁:获取到外函数的锁时,内部函数的锁也获取到了

独占锁--每次只有一个线程能拿到锁(比如synchronize 和reentrantLock)如上图

 

共享锁--多个线程拿到锁(ReentrantReadWriteLock )如下图,3个读线程都获取锁,但是不允许读写线程和写写线程同时都持有锁,理由很简单。

公平锁--后续等待线程是一个FIFO队列,先排队的先获取锁

非公平锁--线程不排队(默认,效率高)

posted @ 2018-11-28 02:36  sagan15  阅读(1378)  评论(0编辑  收藏  举报