多线程之ReentrantReadWriteLock读写锁实现并发写入和读取

    科技2026-06-14  3

    使用独占锁最大的特点在于其只允许一个线程进行操作,这样在数据更新的时候可以保证操作的完整性.但是在进行数据读取时,独占锁会造成严重的性能问题,为了解决高并发下的快速访问与安全修改,JUC提供了ReentrantReadWriteLock读/写锁,即在读取的时候上读锁,在写入的时候上写锁.这两种锁是互斥的.由JVM进行控制. 在ReentrantReadWriteLock中,读锁属于共享锁.而写锁只允许一个线程进行操作…所以在使用时就需要通过不同的方式获取锁.

    public class Account { //账号名称 private String name; //资产 private double asset; //读写锁 private ReadWriteLock lock=new ReentrantReadWriteLock(); public Account(String name, double asset) { this.name = name; this.asset = asset; } /** * 资产追加 * @param money */ public void saveMoney(double money){ //获取写锁(独占) this.lock.writeLock().lock(); try { this.asset += money; System.out.println(Thread.currentThread().getName()+"修改银行账户数据:"+money+";当前资产:"+this.asset); } catch (Exception e) { e.printStackTrace(); }finally { //释放写锁 this.lock.writeLock().unlock(); } } /** * 获取资产数据 * @return */ public String getAsset(){ //获取读锁(共享) this.lock.readLock().lock(); try { return "账户信息:"+Thread.currentThread().getName()+";账户名称:"+this.name+";总资产:"+asset; } catch (Exception e) { return null; }finally{ //释放读锁 this.lock.readLock().unlock(); } } } public class JUCDemo2 { public static void main(String[] args) { Account accout = new Account("QYF", 0.0); double[] moneys = new double[]{120.0, 100.0, 80.0, 60.0, 40.0, 10.0, 5.0}; //写线程存放资产 for (int i = 0; i < 3; i++) { new Thread(() -> { for (int n = 0; n < moneys.length; n++) { accout.saveMoney(moneys[n]); } }).start(); } //读线程读取数据 for (int i = 0; i < 3; i++) { new Thread(() -> { System.err.println(accout.getAsset()); }).start(); } } }

    输出结果:

    Thread-1修改银行账户数据:120.0;当前资产:120.0 Thread-1修改银行账户数据:100.0;当前资产:220.0 Thread-1修改银行账户数据:80.0;当前资产:300.0 Thread-1修改银行账户数据:60.0;当前资产:360.0 Thread-1修改银行账户数据:40.0;当前资产:400.0 Thread-1修改银行账户数据:10.0;当前资产:410.0 Thread-1修改银行账户数据:5.0;当前资产:415.0 Thread-0修改银行账户数据:120.0;当前资产:535.0 Thread-0修改银行账户数据:100.0;当前资产:635.0 Thread-0修改银行账户数据:80.0;当前资产:715.0 Thread-0修改银行账户数据:60.0;当前资产:775.0 Thread-0修改银行账户数据:40.0;当前资产:815.0 Thread-0修改银行账户数据:10.0;当前资产:825.0 Thread-0修改银行账户数据:5.0;当前资产:830.0 Thread-2修改银行账户数据:120.0;当前资产:950.0 Thread-2修改银行账户数据:100.0;当前资产:1050.0 Thread-2修改银行账户数据:80.0;当前资产:1130.0 Thread-2修改银行账户数据:60.0;当前资产:1190.0 Thread-2修改银行账户数据:40.0;当前资产:1230.0 Thread-2修改银行账户数据:10.0;当前资产:1240.0 Thread-2修改银行账户数据:5.0;当前资产:1245.0 账户信息:Thread-3;账户名称:QYF;总资产:1245.0 账户信息:Thread-5;账户名称:QYF;总资产:1245.0 账户信息:Thread-4;账户名称:QYF;总资产:1245.0

    在程序执行时可以发现写程序采用独占锁的处理方式.多个写线程依次执行.而读线程操作时会有多高线程并行读取.这样既保证了账户数据操作的准确性.也实现了数据的快速读取.

    Processed: 0.015, SQL: 9