《Java并发编程艺术---显示锁,可重入锁,读写锁---02

1. Lock

互斥的,在请求锁时如果该锁别其它线程获取的时候,该线程将会被阻塞,放在该锁的阻塞队列中,当线程释放锁时,被阻塞的线程会被激活来判断是否是阻塞队列的头结点将会获得锁,依次下去。

其中的阻塞队列是FIFO队列,这也是最简单的线程调用策略了。

2. 可重入锁(ReentrantLock)

相对于Lock,可重入锁式支持同一个线程获取锁的。列入递归方法,在方法中还可以调用该方法的。
但是Lock不支持重入,会出现线程被自己阻塞的情况。(当前线程正在运行,当该线程请求锁时,返回的false,这样改线程会被阻塞,这样正在运行的该线程也会被阻塞)

重点知识

  • 如何实现可重入
  • 如何实现公平性(原则是:现请求锁的线程,先获得锁)

公平性

公平

其实就是按照FIFO的原则,每次在等待队列的头部获取线程来得到锁

  • 性能比较低,因为每次都要切换

非公平

  • 默认是非公平的

  • 相比于公平,非公平性能更高,但是可能会产生死锁。

3. 读写锁

将排他锁分成读写锁,也就是将读操做和写操作分开控制。
同一时刻可以允许多个读锁,但是当又写锁时,其它所有的读写操做都要被阻塞,当该读锁释放时,被阻塞的读写操做才恢复。这样保证数据的一直性,保证不会出现脏读的情况。

特点

  • 公平性

  • 可重入性

  • 锁降级(写锁可以降级为读锁)

4. ReentrantReadWriteLock

读写状态的设计

通过将32位整形变量分成高16位和低16位,高16位为写状态,低16位为读状态。
通过位操作来实现对读写状态的维护

写锁的获取与释放

写锁的获取与释放和Lock很类似,因为写锁其实也会是排他锁。同一时刻只有唯一的一个写操作获取写锁。

读锁的获取与释放

锁降级

先获取读锁,准备好写入的数据,在获取读锁,这样就实现了从写锁到读锁的降级。

  • 为什么不直接释放写锁呢?还要获取读锁,这样讲避免,释放写锁之后,其他线程获取写锁将数据更改,但是当前线程是感知不到这种变化的。如果获取读锁,要获取读锁的线程将会被阻塞,这样就避免了这种情况。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章