ReentrantReadWriteLock
所謂的讀寫鎖,是訪問資源共享共享鎖、互斥鎖,若是對資源加了寫鎖,其餘線程沒法獲取寫鎖與讀鎖,可是持有寫鎖的線程,能夠對資源
加讀鎖;若是一個線程對資源加了讀鎖,那麼其餘線程能夠繼續加讀鎖。讀讀共享、讀寫互斥、寫寫互斥
package dmeo9;public class MyAccount { private String oid; private int cash; public MyAccount(){ } public MyAccount(String oid, int cash) { this.oid = oid; this.cash = cash; } public String getOid() { return oid; } public void setOid(String oid) { this.oid = oid; } public int getCash() { return cash; } public void setCash(int cash) { this.cash = cash; }}package dmeo9;import java.util.concurrent.locks.ReadWriteLock;public class User implements Runnable { private String name;//用戶名 private MyAccount myAccount;//操做的帳戶 private int ioCash;//操做的金額 private ReadWriteLock readWriteLock;//讀寫鎖操做鎖須要的鎖 private boolean isCheck;//是否操做? public User() { } public User(String name, MyAccount myAccount, int ioCash, ReadWriteLock readWriteLock, boolean isCheck) { this.name = name; this.myAccount = myAccount; this.ioCash = ioCash; this.readWriteLock = readWriteLock; this.isCheck = isCheck; } public String getName() { return name; } public void setName(String name) { this.name = name; } public MyAccount getMyAccount() { return myAccount; } public void setMyAccount(MyAccount myAccount) { this.myAccount = myAccount; } public int getIoCash() { return ioCash; } public void setIoCash(int ioCash) { this.ioCash = ioCash; } public ReadWriteLock getReadWriteLock() { return readWriteLock; } public void setReadWriteLock(ReadWriteLock readWriteLock) { this.readWriteLock = readWriteLock; } public boolean isCheck() { return isCheck; } public void setCheck(boolean check) { isCheck = check; } @Override public void run() { if (isCheck) { /*獲取讀鎖*/ try { readWriteLock.readLock().lock(); System.err.println("\n讀:" + getName() + "\t正在read 查詢\t" + getMyAccount() + "\t帳戶,當前金額爲:" + myAccount.getCash()); } catch (Exception e) { e.printStackTrace(); } finally { /*釋放讀鎖*/ readWriteLock.readLock().unlock(); } } else { /*獲取寫的鎖*/ try { readWriteLock.writeLock().lock(); System.err.println("寫:" + getName() + "\t正在write 操做\t" + getMyAccount() + "帳戶,當前金額爲:" + myAccount.getCash()); getMyAccount().setCash(getMyAccount().getCash() + getIoCash()); System.err.println("操做成功:金額爲" + getIoCash() + "\t當前金額爲:" + getMyAccount().getCash()+"\n\n"); } catch (Exception e) { e.printStackTrace(); } finally { /*釋放寫鎖*/ /** * 通常用lock或者 readwritelock時,須要把 unlock方法放在一個 fianlly 塊中,由於程序運行的時候可能會 出現一些咱們人爲控制不了的因素,致使鎖一直沒釋放,那其餘線程就進不來了. */ readWriteLock.writeLock().unlock(); } } }}package dmeo9;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class DemoReadWriteLock { public static void main(String[] args){ MyAccount myAccount = new MyAccount("工商銀行95599200901215522",160000); ReadWriteLock readWriteLock = new ReentrantReadWriteLock(false); ExecutorService executorService = Executors.newFixedThreadPool(2); User u1 = new User("張三", myAccount, -4000, readWriteLock, false); User u2 = new User("小明", myAccount, 6000, readWriteLock, false); User u3 = new User("小明", myAccount, -8000, readWriteLock, false); User u4 = new User("小明", myAccount, 800, readWriteLock, false); User u5 = new User("小明他爹", myAccount, 0, readWriteLock, true); executorService.execute(u1); executorService.execute(u2); executorService.execute(u3); executorService.execute(u4); executorService.execute(u5); /*關閉線程池*/ executorService.shutdown(); }}輸出:寫:張三 正在write 操做 dmeo9.MyAccount@1a8fdcaa帳戶,當前金額爲:160000 操做成功:金額爲-4000 當前金額爲:156000 寫:小明 正在write 操做 dmeo9.MyAccount@1a8fdcaa帳戶,當前金額爲:156000 操做成功:金額爲6000 當前金額爲:162000 寫:小明 正在write 操做 dmeo9.MyAccount@1a8fdcaa帳戶,當前金額爲:162000 操做成功:金額爲-8000 當前金額爲:154000 寫:小明 正在write 操做 dmeo9.MyAccount@1a8fdcaa帳戶,當前金額爲:154000 操做成功:金額爲800 當前金額爲:154800 讀:小明他爹 正在read 查詢 dmeo9.MyAccount@1a8fdcaa 帳戶,當前金額爲:154800