ToB企服应用市场:ToB评测及商务社交产业平台

标题: ReentrantReadWriteLock读写锁 [打印本页]

作者: 鼠扑    时间: 2024-1-10 06:47
标题: ReentrantReadWriteLock读写锁
ReentrantReadWriteLock读写锁

乐观锁和悲观锁

乐观锁

乐观锁,就是给需要共享的数据,添加一个版本号version,例如1,每次有线程更新共享数据后,version+1,每次线程进行数据更新时,要比较当前线程持有的数据的版本号,相等则修改,不相等则不修改,支持并发访问。
悲观锁

悲观锁,就是每次只能有一个线程,访问共享的数据,其他线程都阻塞,只有当前线程结束,才会释放锁,其他线程中的一个才能访问,不支持并发访问。
表锁和行锁

表锁

线程涉及到数据库的修改时,其他线程不能修改整个表中的任意行数据,就是表锁,表锁不会出现行锁。
行锁

线程涉及到数据库的修改时,只锁当前的一行,是行锁,可能会出现死锁。
读写锁

读锁是共享锁,写锁是独占锁。都可能出现死锁。
读写锁,一个资源可以被多个读线程访问,或者一个写线程访问,但是不能同时存在读写线程,读写是互斥的,读读是共享的。
案例及代码实现
  1. //1.定义资源类
  2. class MyCache {
  3.     //volatile关键字,共享的数据,在一个线程修改后,被其他线程访问到
  4.     private volatile HashMap<String, Object> hashMap = new HashMap<>();
  5.     private ReadWriteLock rwLock = new ReentrantReadWriteLock();
  6.     //2.定义操作资源类的方法
  7.     public Object get(String key) {
  8.         rwLock.readLock().lock();//读锁
  9.         Object result = null;
  10.         try {
  11.             System.out.println(Thread.currentThread().getName() + "正在读取值" + key);
  12.             TimeUnit.MILLISECONDS.sleep(300);
  13.             result = hashMap.get(key);
  14.             System.out.println(Thread.currentThread().getName() + "读取值完成" + key);
  15.         } catch (InterruptedException e) {
  16.             e.printStackTrace();
  17.         }finally {
  18.             rwLock.readLock().unlock();
  19.         }
  20.         return result;
  21.     }
  22.     public void put(String key, Object value) {
  23.         rwLock.writeLock().lock();//写锁
  24.         try {
  25.             System.out.println(Thread.currentThread().getName() + "正在添加值" + key);
  26.             TimeUnit.MILLISECONDS.sleep(300);
  27.             hashMap.put(key, value);
  28.             System.out.println(Thread.currentThread().getName() + "添加值完成" + key);
  29.         } catch (InterruptedException e) {
  30.             e.printStackTrace();
  31.         }finally {
  32.             rwLock.writeLock().unlock();
  33.         }
  34.     }
  35. }
  36. public class ReadWriteLockDemo {
  37.     public static void main(String[] args) {
  38.         MyCache cache = new MyCache();
  39.         
  40.         //创建线程,向缓存中添加值
  41.         for (int i = 0; i < 5; i++) {
  42.             final int num = i;
  43.             new Thread(() -> {
  44.                 cache.put(num + "", num);
  45.             }, String.valueOf(i)).start();
  46.         }
  47.         //创建线程,向缓存中获取值
  48.         for (int i = 0; i < 5; i++) {
  49.             final int num = i;
  50.             new Thread(() -> {
  51.                 cache.get(num + "");
  52.             }, String.valueOf(i)).start();
  53.         }
  54.     }
  55. }
复制代码
读写锁的演变


读写锁的降级


降级案例及代码
  1. /**
  2. * @author 长名06
  3. * @version 1.0
  4. * 读写锁降级演示
  5. */
  6. public class ReadWriteLockDownLevelDemo {
  7.     public static void main(String[] args) {
  8.         ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
  9.         ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();//写锁
  10.         ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();//读锁
  11.                 //先读后写,获取读锁后,就获取不到写锁,线程阻塞
  12.         //1.获取写锁
  13.         writeLock.lock();
  14.         System.out.println("获取写锁");
  15.         //2.获取读锁
  16.         readLock.lock();
  17.         System.out.println("获取读锁");
  18.         //3.释放写锁
  19.         writeLock.unlock();
  20.         //4.释放读锁
  21.         readLock.unlock();
  22.     }
  23. }
复制代码
小结


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4