• 生产者、消费者问题


    线程六个状态:

    1. public enum State {
    2. /**
    3. * 新生
    4. */
    5. NEW,
    6. /**
    7. * 运行
    8. */
    9. RUNNABLE,
    10. /**
    11. *阻塞
    12. */
    13. BLOCKED,
    14. /**
    15. * 等待
    16. */
    17. WAITING,
    18. /**
    19. * 超时等待
    20. */
    21. TIMED_WAITING,
    22. /**
    23. 死亡
    24. **/
    25. TERMINATED;
    26. }

     synchronized和lock的区别

    1、synchronized是关键字,lock是类

    2、synchronized全自动获取释放,lock手动

    3、synchronized标识后,线程A执行,线程B会一直等待,lock可以中途释放

    4、synchronized适合少量的数代码,lock用于大亮代码加锁。

    经典问题,生产者、消费者

    1. public static void main(String[] args) {
    2. t2 t2 = new t2();
    3. new Thread(() -> {
    4. for (int i = 0; i < 50; i++) {
    5. try {
    6. t2.add();
    7. } catch (InterruptedException e) {
    8. throw new RuntimeException(e);
    9. }
    10. }
    11. }).start();
    12. new Thread(() -> {
    13. for (int i = 0; i < 50; i++) {
    14. try {
    15. t2.delete();
    16. } catch (InterruptedException e) {
    17. throw new RuntimeException(e);
    18. }
    19. }
    20. }).start();
    21. }
    22. int sum = 0;
    23. public synchronized void add() throws InterruptedException {
    24. //while(sum==0)
    25. if (sum != 0) {
    26. this.wait();
    27. }
    28. sum++;
    29. System.out.println(sum + "生产了一个东西");
    30. this.notify();
    31. }
    32. public synchronized void delete() throws InterruptedException {
    33. //while(sum==0)
    34. if (sum == 0) {
    35. this.wait();
    36. }
    37. sum--;
    38. System.out.println(sum + "使用了一个东西");
    39. this.notify();
    40. }

    以上代码看着和用着都没问题,问题出在,一旦我多几个线程运行就会出现数据错误:

    而且还有几率一直某一个线程处于等待状态,无法被唤醒 :

    我的理解是cpu执行的数据很快,假如在某一刻A线程处于等待,B线程也处于等待,此时C线程唤醒了,这两个同时被唤醒,就出现了多次消费,虚假唤醒,其实就只能消费一次。

    所以我们不能使用一次if作为判断,应该使用while作为判断,

    然后就是使用java多线程包下的Condition ,它也可以阻塞、唤醒线程,它还有一个优势就是可以指定唤醒某一个线程。

    1. package com.quxiao.controller;
    2. import java.util.concurrent.locks.Condition;
    3. import java.util.concurrent.locks.Lock;
    4. import java.util.concurrent.locks.ReentrantLock;
    5. /**
    6. * @program: package1
    7. * @author: quxiao
    8. * @create: 2023-09-27 15:22
    9. **/
    10. public class t3 {
    11. public static void main(String[] args) {
    12. t3 t3 = new t3();
    13. new Thread(() -> {
    14. for (int i = 0; i < 10; i++) {
    15. t3.a();
    16. }
    17. }, "a").start();
    18. new Thread(() -> {
    19. for (int i = 0; i < 10; i++) {
    20. t3.b();
    21. }
    22. }, "b").start();
    23. new Thread(() -> {
    24. for (int i = 0; i < 10; i++) {
    25. t3.c();
    26. }
    27. }, "c").start();
    28. }
    29. int sum = 1;
    30. Lock lock = new ReentrantLock();
    31. Condition aLock = lock.newCondition();
    32. Condition bLock = lock.newCondition();
    33. Condition cLock = lock.newCondition();
    34. void a() {
    35. lock.lock();
    36. try {
    37. while (sum != 1) {
    38. aLock.await();
    39. }
    40. System.out.println(Thread.currentThread().getName()+":" + "AAAA");
    41. sum = 2;
    42. bLock.signal();
    43. } catch (InterruptedException e) {
    44. throw new RuntimeException(e);
    45. } finally {
    46. lock.unlock();
    47. }
    48. }
    49. void b() {
    50. lock.lock();
    51. try {
    52. while (sum != 2) {
    53. bLock.await();
    54. }
    55. System.out.println(Thread.currentThread().getName()+":" + "BBBB");
    56. sum = 3;
    57. cLock.signal();
    58. } catch (InterruptedException e) {
    59. throw new RuntimeException(e);
    60. } finally {
    61. lock.unlock();
    62. }
    63. }
    64. void c() {
    65. lock.lock();
    66. try {
    67. while (sum != 3) {
    68. cLock.await();
    69. }
    70. System.out.println(Thread.currentThread().getName()+":" + "CCCC");
    71. sum = 1;
    72. aLock.signal();
    73. } catch (InterruptedException e) {
    74. throw new RuntimeException(e);
    75. } finally {
    76. lock.unlock();
    77. }
    78. }
    79. }

  • 相关阅读:
    go语言基本操作---六
    数据分析思维与模型:群组分析法
    Java学习 (九)基础篇 包机制&JavaDoc
    注意这几种职场情况
    前端培训丁鹿学堂:vue性能优化总结(二)
    入门力扣自学笔记127 C++ (题目编号1224)
    无人机运营合格证及无人机服务资质认证详解
    Rsync远程数据同步
    GD32F470引脚外部中断测试
    钱小雨--进
  • 原文地址:https://blog.csdn.net/qx020814/article/details/132944550