Lock

锁 - 图1

tryLock() 代码示例

  • 看下注释
    1. ReentrantLock lock = new ReentrantLock();
    2. Runnable runnable = () -> {
    3. // 1. 获取锁的时候可能会被中断,中断就不需要拿锁了
    4. try {
    5. if (lock.tryLock(1, TimeUnit.SECONDS)) {
    6. // 2. 要确保拿到锁之后进行解锁
    7. try {
    8. System.out.println(Thread.currentThread().getName() + "拿到锁了");
    9. TimeUnit.MILLISECONDS.sleep(800);
    10. } finally {
    11. lock.unlock();
    12. }
    13. } else {
    14. System.out.println(Thread.currentThread().getName() + "没有到锁了");
    15. }
    16. } catch (InterruptedException e) {
    17. e.printStackTrace();
    18. }
    19. };

lockInterruptibly

  1. ReentrantLock lock = new ReentrantLock();
  2. Runnable runnable = () -> {
  3. try {
  4. lock.lockInterruptibly();
  5. try{
  6. System.out.println("拿到锁了");
  7. TimeUnit.MILLISECONDS.sleep(800);
  8. } catch (InterruptedException e) {
  9. System.out.println("获得锁后被中断");
  10. } finally {
  11. lock.unlock();
  12. }
  13. } catch (InterruptedException e) {
  14. System.out.println("获得锁期间被中断");
  15. }
  16. };
  17. Thread a = new Thread(runnable);
  18. a.start();
  19. // 1. 要求获得锁之后中断
  20. // TimeUnit.MILLISECONDS.sleep(200);
  21. // a.interrupt();
  22. // 获得锁期间被中断
  23. // 2. a.interrupt();

锁的分类

锁 - 图2

乐观锁悲观锁

锁 - 图3

可重入/递归锁

锁 - 图4

公平/非公平

锁 - 图5

共享锁/排他锁

锁 - 图6

读写锁使用代码

  1. public class TryLockTest {
  2. // 创建读写锁
  3. private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  4. // 拿到读写锁实例的读锁
  5. private static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
  6. // 拿到读写锁实例的写锁
  7. private static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
  8. // 读操作
  9. public static void read() {
  10. readLock.lock();
  11. try {
  12. System.out.println(Thread.currentThread().getName() + "获得了读锁");
  13. TimeUnit.MILLISECONDS.sleep(500);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. } finally {
  17. System.out.println(Thread.currentThread().getName() + "准备解除读锁");
  18. readLock.unlock();
  19. }
  20. }
  21. // 写操作
  22. public static void write() {
  23. writeLock.lock();
  24. try {
  25. System.out.println(Thread.currentThread().getName() + "获得了写锁");
  26. TimeUnit.MILLISECONDS.sleep(800);
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. } finally {
  30. System.out.println(Thread.currentThread().getName() + "准备解除写锁");
  31. writeLock.unlock();
  32. }
  33. }
  34. public static void testReentrantReadWriteLock() throws InterruptedException {
  35. int size = 10;
  36. Runnable read = ()-> {
  37. read();
  38. };
  39. Runnable write = ()-> {
  40. write();
  41. };
  42. // 一半进行共享读
  43. Thread[] threads = new Thread[size];
  44. for (int i=0; i<size / 2; i++) {
  45. threads[i] = new Thread(read);
  46. }
  47. // 一半进行排他写
  48. for (int i=size/2; i<size; i++) {
  49. threads[i] = new Thread(write);
  50. }
  51. for (int i=0; i<size; i++) {
  52. threads[i].start();
  53. }
  54. for (int i=0; i<size; i++) {
  55. threads[i].join();
  56. }
  57. }
  58. }
  • 打印
    1. Thread-0获得了读锁
    2. Thread-1获得了读锁
    3. Thread-2获得了读锁
    4. Thread-3获得了读锁
    5. Thread-4获得了读锁
    6. Thread-0准备解除读锁
    7. Thread-3准备解除读锁
    8. Thread-1准备解除读锁
    9. Thread-2准备解除读锁
    10. Thread-4准备解除读锁
    11. Thread-5获得了写锁
    12. Thread-5准备解除写锁
    13. Thread-6获得了写锁
    14. Thread-6准备解除写锁
    15. Thread-7获得了写锁
    16. Thread-7准备解除写锁
    17. Thread-8获得了写锁
    18. Thread-8准备解除写锁
    19. Thread-9获得了写锁
    20. Thread-9准备解除写锁

自选锁

锁 - 图7

可中断

锁 - 图8

锁的优化

锁 - 图9