• ReentrantLock实现公平锁,可中断,条件变量,可重入案例


    1.ReentrantLock实现公平锁

    1. /**
    2. * ReentrantLock实现公平锁
    3. * 创建了三个线程,依次打印线程
    4. */
    5. public class FairLockExample {
    6. private static ReentrantLock fairLock = new ReentrantLock(true); // 创建公平锁
    7. public static void main(String[] args) {
    8. Runnable fairTask = new FairTask();
    9. // 创建多个线程来竞争公平锁
    10. Thread thread1 = new Thread(fairTask, "Thread-1");
    11. Thread thread2 = new Thread(fairTask, "Thread-2");
    12. Thread thread3 = new Thread(fairTask, "Thread-3");
    13. thread1.start();
    14. thread2.start();
    15. thread3.start();
    16. }
    17. static class FairTask implements Runnable {
    18. @Override
    19. public void run() {
    20. while (true) {
    21. try {
    22. fairLock.lock();
    23. System.out.println(Thread.currentThread().getName() + " 获取到锁");
    24. Thread.sleep(1000);
    25. } catch (InterruptedException e) {
    26. e.printStackTrace();
    27. } finally {
    28. fairLock.unlock();
    29. System.out.println(Thread.currentThread().getName() + " 释放锁");
    30. }
    31. }
    32. }
    33. }
    34. }

    输出结果

    1. Thread-1 获取到锁
    2. Thread-1 释放锁
    3. Thread-2 获取到锁
    4. Thread-2 释放锁
    5. Thread-3 获取到锁
    6. Thread-3 释放锁
    7. Thread-1 获取到锁
    8. Thread-1 释放锁
    9. Thread-2 获取到锁
    10. Thread-2 释放锁
    11. Thread-3 获取到锁
    12. Thread-3 释放锁
    13. Thread-1 获取到锁
    14. Thread-1 释放锁
    15. Thread-2 获取到锁
    16. Thread-2 释放锁
    17. Thread-3 获取到锁

    2.ReentrantLock实现可中断锁

    1. /**
    2. * 演示ReentrantLock调用lockInterruptibly方法可以被中断
    3. * https://blog.csdn.net/ZSA222/article/details/123433746?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170022637516800182740333%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170022637516800182740333&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-123433746-null-null.142^v96^pc_search_result_base5&utm_term=ReentrantLock&spm=1018.2226.3001.4187
    4. */
    5. public class ReentrantLockInterrupt {
    6. private static ReentrantLock lock = new ReentrantLock();
    7. public static void main(String[] args) throws InterruptedException {
    8. Thread thread = new Thread(() -> {
    9. try {
    10. // 如果没有竞争那么此方法就会获取 lock 对象锁
    11. // 如果有竞争就进入阻塞队列,可以被其它线程用 interruput 方法打断
    12. System.out.println(Thread.currentThread().getName() + LocalDateTime.now() + "尝试获得锁");
    13. Thread.sleep(15000);
    14. lock.lockInterruptibly();
    15. } catch (InterruptedException e) {
    16. e.printStackTrace();
    17. System.out.println(Thread.currentThread().getName() + LocalDateTime.now() + "t1线程没有获得锁,被打断...return");
    18. return;
    19. }
    20. try {
    21. System.out.println(Thread.currentThread().getName() + LocalDateTime.now() + "t1线程获得了锁");
    22. } finally {
    23. lock.unlock();
    24. }
    25. }, "t1");
    26. // t1启动前 主线程先获得了锁
    27. lock.lock();
    28. thread.start(); // thread线程会进入阻塞队列
    29. Thread.sleep(5000);
    30. System.out.println(Thread.currentThread().getName() + LocalDateTime.now() + "interrupt...打断t1");
    31. Thread.sleep(2000);
    32. thread.interrupt();
    33. }
    34. }

    输出结果

    1. t111:27:23尝试获得锁
    2. main11:27:28interrupt...打断t1
    3. java.lang.InterruptedException: sleep interrupted
    4. at java.lang.Thread.sleep(Native Method)
    5. at concurrentpro.lock.ReentrantLockInterrupt.lambda$main$0(ReentrantLockInterrupt.java:20)
    6. at java.lang.Thread.run(Thread.java:750)
    7. t111:27:30t1线程没有获得锁,被打断...return
    1. /**
    2. * 演示ReentrantLock调用普通lock方法,不能被中断
    3. * https://blog.csdn.net/ZSA222/article/details/123433746?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170022637516800182740333%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170022637516800182740333&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-123433746-null-null.142^v96^pc_search_result_base5&utm_term=ReentrantLock&spm=1018.2226.3001.4187
    4. */
    5. public class ReentrantLock {
    6. private static java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock();
    7. public static void main(String[] args) throws InterruptedException {
    8. Thread thread = new Thread(() -> {
    9. System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + Thread.currentThread().getName() + "尝试获得锁");
    10. lock.lock();
    11. try {
    12. System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + Thread.currentThread().getName() + "t1线程获得了锁");
    13. } finally {
    14. lock.unlock();
    15. }
    16. }, "t1");
    17. // t1启动前 主线程先获得了锁
    18. lock.lock();
    19. thread.start();
    20. Thread.sleep(1000);
    21. System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + Thread.currentThread().getName() + "interrupt...打断t1");
    22. thread.interrupt();
    23. }
    24. }

    输出结果 

    1. 11:24:39t1尝试获得锁
    2. 11:24:40maininterrupt...打断t1

    3.ReentrantLock实现条件变量

    1. /**
    2. * ReentrantLock 之 condtion的用法
    3. * 配合 condition.await 和 condition.signal
    4. * 来源:bilibli 黑马程序员之并发编程
    5. */
    6. public class ConditionVariable {
    7. private static boolean hasCigarette = false;
    8. private static boolean hasTakeout = false;
    9. private static final ReentrantLock lock = new ReentrantLock();
    10. // 等待烟的休息室(条件变量)
    11. static Condition waitCigaretteSet = lock.newCondition();
    12. // 等外卖的休息室(条件变量)
    13. static Condition waitTakeoutSet = lock.newCondition();
    14. public static void main(String[] args) throws InterruptedException {
    15. new Thread(() -> {
    16. lock.lock();
    17. try {
    18. System.out.println(LocalTime.now() + Thread.currentThread().getName() + "有烟没?[{}]" + hasCigarette);
    19. while (!hasCigarette) {
    20. System.out.println(LocalTime.now() + Thread.currentThread().getName() +"没烟,先歇会!");
    21. try {
    22. // 此时小南进入到 等烟的休息室
    23. waitCigaretteSet.await();
    24. } catch (InterruptedException e) {
    25. e.printStackTrace();
    26. }
    27. }
    28. System.out.println(LocalTime.now() + Thread.currentThread().getName() + "烟来咯, 可以开始干活了");
    29. } finally {
    30. lock.unlock();
    31. }
    32. }, "小南").start();
    33. new Thread(() -> {
    34. lock.lock();
    35. try {
    36. System.out.println(LocalTime.now() + Thread.currentThread().getName() +"外卖送到没?[{}]" + hasTakeout);
    37. while (!hasTakeout) {
    38. System.out.println(LocalTime.now() + Thread.currentThread().getName() + "没外卖,先歇会!");
    39. try {
    40. // 此时小女进入到 等外卖的休息室
    41. waitTakeoutSet.await();
    42. } catch (InterruptedException e) {
    43. e.printStackTrace();
    44. }
    45. }
    46. System.out.println(LocalTime.now() + Thread.currentThread().getName() +"外卖来咯, 可以开始干活了");
    47. } finally {
    48. lock.unlock();
    49. }
    50. }, "小女").start();
    51. Thread.sleep(1000);
    52. new Thread(() -> {
    53. lock.lock();
    54. try {
    55. System.out.println(LocalTime.now() + Thread.currentThread().getName() + "送外卖的来咯~");
    56. hasTakeout = true;
    57. // 唤醒等外卖的小女线程
    58. waitTakeoutSet.signal();
    59. } finally {
    60. lock.unlock();
    61. }
    62. }, "送外卖的").start();
    63. Thread.sleep(1000);
    64. new Thread(() -> {
    65. lock.lock();
    66. try {
    67. System.out.println(LocalTime.now() + Thread.currentThread().getName() +"送烟的来咯~");
    68. hasCigarette = true;
    69. // 唤醒等烟的小南线程
    70. waitCigaretteSet.signal();
    71. } finally {
    72. lock.unlock();
    73. }
    74. }, "送烟的").start();
    75. }
    76. }

    输出结果

    1. 11:29:38.644小南有烟没?[{}]false
    2. 11:29:38.645小南没烟,先歇会!
    3. 11:29:38.645小女外卖送到没?[{}]false
    4. 11:29:38.645小女没外卖,先歇会!
    5. 11:29:39.620送外卖的送外卖的来咯~
    6. 11:29:39.620小女外卖来咯, 可以开始干活了
    7. 11:29:40.621送烟的送烟的来咯~
    8. 11:29:40.621小南烟来咯, 可以开始干活了

    4.ReentrantLock实现可重入

    1. public class ReentrantLockExample {
    2. private ReentrantLock lock = new ReentrantLock();
    3. public void performTask() {
    4. lock.lock();
    5. try {
    6. System.out.println("Task started");
    7. // 可以多次获取锁
    8. lock.lock();
    9. try {
    10. System.out.println("Task is performing");
    11. } finally {
    12. lock.unlock();
    13. System.out.println("Inner lock released");
    14. }
    15. System.out.println("Task completed");
    16. } finally {
    17. lock.unlock();
    18. System.out.println("Outer lock released");
    19. }
    20. }
    21. public static void main(String[] args) {
    22. ReentrantLockExample example = new ReentrantLockExample();
    23. example.performTask();
    24. }
    25. }

    输出结果

    1. Task started
    2. Task is performing
    3. Inner lock released
    4. Task completed
    5. Outer lock released

  • 相关阅读:
    Java中的LinkedHashSet使用[71]
    JavaScript继承的几种方式
    【每天学习一点新知识】网络安全--拒绝服务攻击
    PEG功能化/修饰/偶联中空二氧化硅纳米球 PEG-Hollow SiO2 nanosphere
    【Java】Servlet API
    【GAN入门】生成 AI的概念
    第7章 SpringMVC
    navicat连接postgresql报错解决方案
    220V转18V非隔离降压芯片:满足多种应用需求
    c++图片取出每一个像素的值
  • 原文地址:https://blog.csdn.net/xuan__xia/article/details/134475948