ReentrantReadWriteLock
    所谓的读写锁,是访问资源共享共享锁、互斥锁,如果对资源加了写锁,其他线程无法获取写锁与读锁,但是持有写锁的线程,可以对资源
    加读锁;如果一个线程对资源加了读锁,那么其他线程可以继续加读锁。读读共享、读写互斥、写写互斥
  1. package dmeo9;
  2. public class MyAccount {
  3. private String oid;
  4. private int cash;
  5. public MyAccount(){
  6. }
  7. public MyAccount(String oid, int cash) {
  8. this.oid = oid;
  9. this.cash = cash;
  10. }
  11. public String getOid() {
  12. return oid;
  13. }
  14. public void setOid(String oid) {
  15. this.oid = oid;
  16. }
  17. public int getCash() {
  18. return cash;
  19. }
  20. public void setCash(int cash) {
  21. this.cash = cash;
  22. }
  23. }
  1. package dmeo9;
  2. import java.util.concurrent.locks.ReadWriteLock;
  3. public class User implements Runnable {
  4. private String name;//用户名
  5. private MyAccount myAccount;//操作的账户
  6. private int ioCash;//操作的金额
  7. private ReadWriteLock readWriteLock;//读写锁操作锁需要的锁
  8. private boolean isCheck;//是否操作?
  9. public User() {
  10. }
  11. public User(String name, MyAccount myAccount, int ioCash, ReadWriteLock readWriteLock, boolean isCheck) {
  12. this.name = name;
  13. this.myAccount = myAccount;
  14. this.ioCash = ioCash;
  15. this.readWriteLock = readWriteLock;
  16. this.isCheck = isCheck;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public MyAccount getMyAccount() {
  25. return myAccount;
  26. }
  27. public void setMyAccount(MyAccount myAccount) {
  28. this.myAccount = myAccount;
  29. }
  30. public int getIoCash() {
  31. return ioCash;
  32. }
  33. public void setIoCash(int ioCash) {
  34. this.ioCash = ioCash;
  35. }
  36. public ReadWriteLock getReadWriteLock() {
  37. return readWriteLock;
  38. }
  39. public void setReadWriteLock(ReadWriteLock readWriteLock) {
  40. this.readWriteLock = readWriteLock;
  41. }
  42. public boolean isCheck() {
  43. return isCheck;
  44. }
  45. public void setCheck(boolean check) {
  46. isCheck = check;
  47. }
  48. @Override
  49. public void run() {
  50. if (isCheck) {
  51. /*获取读锁*/
  52. try {
  53. readWriteLock.readLock().lock();
  54. System.err.println("\n读:" + getName() + "\t正在read 查询\t" + getMyAccount() + "\t账户,当前金额为:" + myAccount.getCash());
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. } finally {
  58. /*释放读锁*/
  59. readWriteLock.readLock().unlock();
  60. }
  61. } else {
  62. /*获取写的锁*/
  63. try {
  64. readWriteLock.writeLock().lock();
  65. System.err.println("写:" + getName() + "\t正在write 操作\t" + getMyAccount() + "账户,当前金额为:" + myAccount.getCash());
  66. getMyAccount().setCash(getMyAccount().getCash() + getIoCash());
  67. System.err.println("操作成功:金额为" + getIoCash() + "\t当前金额为:" + getMyAccount().getCash()+"\n\n");
  68. } catch (Exception e) {
  69. e.printStackTrace();
  70. } finally {
  71. /*释放写锁*/
  72. /**
  73. * 一般用lock或者 readwritelock时,需要把
  74. unlock方法放在一个 fianlly 块中,因为程序运行的时候可能会
  75. 出现一些我们人为控制不了的因素,导致锁一直没释放,那其他线程就进不来了.
  76. */
  77. readWriteLock.writeLock().unlock();
  78. }
  79. }
  80. }
  81. }
  1. package dmeo9;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.locks.ReadWriteLock;
  5. import java.util.concurrent.locks.ReentrantReadWriteLock;
  6. public class DemoReadWriteLock {
  7. public static void main(String[] args){
  8. MyAccount myAccount = new MyAccount("工商银行95599200901215522",160000);
  9. ReadWriteLock readWriteLock = new ReentrantReadWriteLock(false);
  10. ExecutorService executorService = Executors.newFixedThreadPool(2);
  11. User u1 = new User("张三", myAccount, -4000, readWriteLock, false);
  12. User u2 = new User("小明", myAccount, 6000, readWriteLock, false);
  13. User u3 = new User("小明", myAccount, -8000, readWriteLock, false);
  14. User u4 = new User("小明", myAccount, 800, readWriteLock, false);
  15. User u5 = new User("小明他爹", myAccount, 0, readWriteLock, true);
  16. executorService.execute(u1);
  17. executorService.execute(u2);
  18. executorService.execute(u3);
  19. executorService.execute(u4);
  20. executorService.execute(u5);
  21. /*关闭线程池*/
  22. executorService.shutdown();
  23. }
  24. }
  25. 输出:
  26. 写:张三 正在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

23.读写锁ReadWriteLock的更多相关文章

  1. 线程中的读写锁ReadWriteLock

    Lock锁还有两个非常强大的类 ReadWriteLock接口实现类ReentrantReadWriteLock(非常重要的锁) 想实现 读取的时候允许多线程并发访问,写入的时候不允许. 这种效果.. ...

  2. 显式锁(三)读写锁ReadWriteLock

    前言:   上一篇文章,已经很详细地介绍了 显式锁Lock 以及 其常用的实现方式- - ReetrantLock(重入锁),本文将介绍另一种显式锁 - - 读写锁ReadWriteLock.    ...

  3. 【漫画】互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock

    ReentrantLock完美实现了互斥,完美解决了并发问题.但是却意外发现它对于读多写少的场景效率实在不行.此时ReentrantReadWriteLock来救场了!一种适用于读多写少场景的锁,可以 ...

  4. 【漫画】读写锁ReadWriteLock还是不够快?再试试StampedLock!

    本文来源于公众号[胖滚猪学编程] 转载请注明出处! 在互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock一文中,我们对比了互斥锁ReentrantLock和读写锁ReadWr ...

  5. 读-写锁 ReadWriteLock & 线程八锁

    读-写锁 ReadWriteLock: ①ReadWriteLock 维护了一对相关的锁,一个用于只读操作, 另一个用于写入操作. 只要没有 writer,读取锁可以由 多个 reader 线程同时保 ...

  6. C# 多线程编程之锁的使用【互斥锁(lock)和读写锁(ReadWriteLock)】

    多线程编程之锁的使用[互斥锁(lock)和读写锁(ReadWriteLock)] http://blog.csdn.net/sqqyq/article/details/18651335 多线程程序写日 ...

  7. Java 读写锁 ReadWriteLock 原理与应用场景详解

    Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理@mikechen 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Loc ...

  8. 深入理解读写锁—ReadWriteLock源码分析

    转载:https://blog.csdn.net/qq_19431333/article/details/70568478 ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁.读锁可以在 ...

  9. 读写锁ReadWriteLock和缓存实例

    读写锁:多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥.即:读的时候不允许写,写的时候不允许读,可以同时读.      synchronized关键字和普通的Lock构造的锁,会造成读与读之间的互斥, ...

随机推荐

  1. vue 中 使用 tradingview

    加载页面时初始化方法: mounted 可以在 mounted 方法中调用 methods 的中的方法 使用 data 中的数据时,在每个方法的开始推荐先定义 var that = this 现在还不 ...

  2. chromedriver与chrome版本对应表,firefox、geckodriver

     一. chromedriver与chrome对应表(记得就会更新): chromedriver版本 支持的Chrome版本 v2.36 v64-66 v2.35 v62-64 v2.34 v61-6 ...

  3. [CodeChef - STREETTA] The Street 李超线段树

    大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X ...

  4. 二、redis系列之持久化

    1. 绪言 redis是一种内存数据库,它把数据存储在服务器的内存当中,这样极大地保证了redis数据库的性能,但也为数据安全带来了隐患——redis所在服务器重启或者发生宕机后,redis数据库里的 ...

  5. 试水jdk8 stream

    jdk8出来日子不短了,jdk11都出来了,不过用的最多的不过是1.5罢了. 今年终于鼓起勇气认真对待它,在18年记录下学习stream,画上一个圆. 先看个图 Java8中有两大最为重要的改变.第一 ...

  6. 从Table 表中取出第 m 条到第 n 条的记录

    * FROM Table id FROM Table )) --从TABLE表中取出第m到n条记录 (Exists版本) * FROM TABLE AS a WHERE Not Exists ( * ...

  7. input用类写的方法

  8. C# NPOCO 轻量级ORM框架(入门)

    目前公司使用这个框架,搜不到很详细的中文资料. 只有英文wiki,所以翻译学习一下. 因为博主也是低水平的,可能会有一些理解不到位的地方. 可能会有错误的地方,如果有园友发现可以指出. wiki地址: ...

  9. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  10. PHP 操作MySQL时mysql_connect( )和Mysqli( )的两种报错机制

    刚开始使用PHP连接MySQL数据库的时候,如果数据库连接不成功或者,对MySQL数据库进行增删改查等操作的时候,SQL语句存在错误,而在执行PHP文件的时候,浏览器并不会抛出错误的原因,一般是空白显 ...