1、锁的说明

image.png
悲观锁:不支持并发操作,在一个人对账户进行修改时,会将这条记录进行上锁,其他人无法进行操作,只能一个一个地进行。
乐观锁:在一个人对账户进行修改时,此时该条记录的版本号会被修改,另外一个人再对此条记录进行修改时,其手上拿到的版本号会与数据库中的本版号进行比对,一致则可提交成功,否则失败。
表锁:在对该表格某一条记录进行修改时,会将整个表格锁定,其他人无法对该表进行操作。
行锁:在对表格中的某条记录进行操作时,会将该条记录的数据进行锁定,其他人无法对该条记录进行操作。行锁会发生死锁。
读锁:共享锁,发生死锁。
写锁:独占锁,发送死锁。
image.png

2、读写锁案例演示

不加读锁跟写锁的话会出现错误的现象。

  1. class MyCache {
  2. //创建HashMap
  3. public volatile Map<String, Object> map = new HashMap<>();
  4. //创建读写锁对象
  5. private ReadWriteLock rwLock = new ReentrantReadWriteLock();
  6. //写操作
  7. public void put(String key, Object obj) {
  8. //写锁加锁
  9. rwLock.writeLock().lock();
  10. try {
  11. System.out.println(Thread.currentThread().getName() + "正在进行写操作" + key);
  12. TimeUnit.MICROSECONDS.sleep(300);
  13. map.put(key, obj);
  14. System.out.println(Thread.currentThread().getName() + "写完了" + key);
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. } finally {
  18. //释放写锁
  19. rwLock.writeLock().unlock();
  20. }
  21. }
  22. //读操作
  23. public Object get(String key) {
  24. //读锁加锁
  25. rwLock.readLock().lock();
  26. Object obj = null;
  27. try {
  28. System.out.println(Thread.currentThread().getName() + "正在进行读操作" + key);
  29. TimeUnit.MICROSECONDS.sleep(300);
  30. obj = map.get(key);
  31. System.out.println(Thread.currentThread().getName() + "读完了" + key);
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. } finally {
  35. //释放写锁
  36. rwLock.readLock().unlock();
  37. }
  38. return obj;
  39. }
  40. }
  41. public class ReadWriteLockDemo {
  42. public static void main(String[] args) {
  43. MyCache myCache = new MyCache();
  44. for (int i = 1; i <= 5; i++) {
  45. int finalI = i;
  46. new Thread(() -> {
  47. myCache.put(finalI + "", finalI + "");
  48. }, String.valueOf(i)).start();
  49. }
  50. for (int i = 1; i <= 5; i++) {
  51. int finalI = i;
  52. new Thread(() -> {
  53. System.out.println(myCache.get(finalI + ""));
  54. }, String.valueOf(i)).start();
  55. }
  56. }
  57. }

3、锁的降级-案例演示

image.png
image.png

  1. public class LockLower {
  2. public static void main(String[] args) {
  3. ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
  4. ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();//获取读锁
  5. ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();//获取写锁
  6. //1、写锁加锁
  7. writeLock.lock();
  8. System.out.println("写锁降级,写的内容......");
  9. //2、获取读锁
  10. readLock.lock();
  11. System.out.println("读锁读取内容");
  12. //3、释放写锁
  13. writeLock.unlock();
  14. //4、释放读锁
  15. readLock.unlock();
  16. }
  17. }