java併發初探ReentrantWriteReadLock
ReenWriteReadLock類的優秀博客
ReentrantReadWriteLock讀寫鎖詳解 Java多線程系列--「JUC鎖」08之 共享鎖和ReentrantReadWriteLockhtml
ReentrantWriteReadLock類實現
@startuml interface Lock interface ReadWriteLock class ReentrantReadWriteLock{ Sync sync ReentrantReadWriteLock.ReadLock readerLock; ReentrantReadWriteLock.WriteLock writerLock; } ReadWriteLock <|-- ReentrantReadWriteLock ReentrantReadWriteLock --o ReadLock ReentrantReadWriteLock --o WriteLock ReentrantReadWriteLock --o Sync AbstractQueuedSynchronizer <|- Sync Lock <|-- ReadLock Lock <|-- WriteLock @enduml
特色
ReentrantWriteReadLock內部有讀鎖和寫鎖。 寫鎖是獨佔鎖 當前線程持有寫鎖,其餘線程只能等待 當其餘線程擁有對象的寫鎖或者讀鎖,當前線程等待獲取寫鎖 讀鎖是共享鎖 沒有其餘線程的寫鎖,當前線程能夠獲取讀鎖java
使用例子
package com.java.javabase.thread.base.concurrent.lock; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @Slf4j public class ReentranReadWriteLockTest { /** * @author * @version * @since */ public static void main(String[] args) { ReentranReadWriteLockTest test =new ReentranReadWriteLockTest(); User user =test.new User("jack",test.new Count("001",1000)); for(int i=0;i<3;i++) { user.printCash(); user.setCash(1000); } } @Data @AllArgsConstructor @NoArgsConstructor class Count { private String id; private int cash; } @Data class User { private String name; private Count count; private ReadWriteLock readWriteLock; public User(String name, Count count) { this.name = name; this.count = count; this.readWriteLock = new ReentrantReadWriteLock(); } public void setCash(final int cash) { new Thread() { @Override public void run() { readWriteLock.writeLock().lock(); try { log.info("thread {} :user {} set cash {} start", Thread.currentThread().getName(), name, cash); Thread.sleep(1000); log.info("thread {} :user {} current cash = {}", Thread.currentThread().getName(), name, count.getCash()); count.setCash(cash); log.info("thread {} :user {} set cash {} end", Thread.currentThread().getName(), name, cash); } catch (InterruptedException e) { e.printStackTrace(); } finally { readWriteLock.writeLock().unlock(); } } }.start(); } public void printCash() { new Thread() { @Override public void run() { try { readWriteLock.readLock().lock(); log.info("thread {} :user {} get cash start", Thread.currentThread().getName(), name); log.info("thread {} :user {} current cash = {}", Thread.currentThread().getName(), name, count.getCash()); Thread.sleep(1000); log.info("thread {} :user {} get cash end", Thread.currentThread().getName(), name); } catch (InterruptedException e) { e.printStackTrace(); } finally { readWriteLock.readLock().unlock(); } } }.start(); } } }
例子結果
2019-08-09 10:49:15,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack get cash start 2019-08-09 10:49:15,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack current cash = 1000 2019-08-09 10:49:16,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack get cash end 2019-08-09 10:49:16,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 start 2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack current cash = 1000 2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 end 2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash start 2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash start 2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack current cash = 1000 2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack current cash = 1000 2019-08-09 10:49:18,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash end 2019-08-09 10:49:18,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash end 2019-08-09 10:49:18,618 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 start 2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack current cash = 1000 2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 end 2019-08-09 10:49:19,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 start 2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack current cash = 1000 2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 end