并发编程--读写锁ReadWriteLock和ReentrantReadWriteLock(一)

比眉伴天荒 2022-06-17 08:07 286阅读 0赞

Java并发编程包提供了读写锁的实现,其维护了一对相关的锁 — — “读取锁”和“写入锁”,一个用于读取操作,另一个用于写入操作。

“读取锁”用于只读操作,它是“共享锁”,能同时被多个线程获取。

“写入锁”用于写入操作,它是“独占锁”,写入锁只能被一个线程锁获取。

ReadWriteLock是一个接口。ReentrantReadWriteLock是它的实现类,ReentrantReadWriteLock包括子类ReadLock和WriteLock。

读写锁接口ReadWriteLock:

(1)readLock获取一个读锁

(2)writeLock获取一个写锁

  1. public interface ReadWriteLock {
  2. Lock readLock();
  3. Lock writeLock();
  4. }

在实现类ReentrantReadWriteLock中并发编程包分别实现了一个读锁ReadLock和写锁WriteLock,其实ReadLock和WriteLock差别不大,比较明显的差别是ReadLock获取锁时是调用acquireShared方法

  1. public void lock() {
  2. sync.acquireShared(1);
  3. }

WriteLock获取锁的方法是sync.acquire(1)

  1. public void lock() {
  2. sync.acquire(1);
  3. }

我们知道读锁是一个共享锁,写锁是一个独占锁,具体的实现区别应该是在acquireShared和acquire中体现的。

读锁ReadLock源码:

  1. public static class ReadLock implements Lock, java.io.Serializable {
  2. private static final long serialVersionUID = -5992448646407690164L;
  3. private final Sync sync;
  4. protected ReadLock(ReentrantReadWriteLock lock) {
  5. sync = lock.sync;
  6. }
  7. public void lock() {
  8. sync.acquireShared(1);
  9. }
  10. public void lockInterruptibly() throws InterruptedException {
  11. sync.acquireSharedInterruptibly(1);
  12. }
  13. public boolean tryLock() {
  14. return sync.tryReadLock();
  15. }
  16. public boolean tryLock(long timeout, TimeUnit unit)
  17. throws InterruptedException {
  18. return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
  19. }
  20. public void unlock() {
  21. sync.releaseShared(1);
  22. }
  23. public Condition newCondition() {
  24. throw new UnsupportedOperationException();
  25. }
  26. public String toString() {
  27. int r = sync.getReadLockCount();
  28. return super.toString() +
  29. "[Read locks = " + r + "]";
  30. }
  31. }

写锁WriteLock源码:

  1. public static class WriteLock implements Lock, java.io.Serializable {
  2. private static final long serialVersionUID = -4992448646407690164L;
  3. private final Sync sync;
  4. protected WriteLock(ReentrantReadWriteLock lock) {
  5. sync = lock.sync;
  6. }
  7. public void lock() {
  8. sync.acquire(1);
  9. }
  10. public void lockInterruptibly() throws InterruptedException {
  11. sync.acquireInterruptibly(1);
  12. }
  13. public boolean tryLock( ) {
  14. return sync.tryWriteLock();
  15. }
  16. public boolean tryLock(long timeout, TimeUnit unit)
  17. throws InterruptedException {
  18. return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  19. }
  20. public void unlock() {
  21. sync.release(1);
  22. }
  23. public Condition newCondition() {
  24. return sync.newCondition();
  25. }
  26. public String toString() {
  27. Thread o = sync.getOwner();
  28. return super.toString() + ((o == null) ?
  29. "[Unlocked]" :
  30. "[Locked by thread " + o.getName() + "]");
  31. }
  32. public boolean isHeldByCurrentThread() {
  33. return sync.isHeldExclusively();
  34. }
  35. public int getHoldCount() {
  36. return sync.getWriteHoldCount();
  37. }
  38. }

发表评论

表情:
评论列表 (有 0 条评论,286人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ReadWriteLock

    现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如