当前位置: 首页 > 编程笔记 >

Java多线程生产者消费者模式实现过程解析

裘嘉树
2023-03-14
本文向大家介绍Java多线程生产者消费者模式实现过程解析,包括了Java多线程生产者消费者模式实现过程解析的使用技巧和注意事项,需要的朋友参考一下

单生产者与单消费者

示例:

public class ProduceConsume {
    public static void main(String[] args) {
      String lock = new String("");
      Produce produce = new Produce(lock);
      Consume consume = new Consume(lock);

      new Thread(() -> {
        while (true) {
          produce.setValue();
        }
      }, "ProductThread").start();
      new Thread(() -> {
        while (true) {
          consume.getValue();
        }
      }, "ConsumeThread").start();
    }

    /**
     * 生产者
     */
    static class Produce {
      private String lock;

      public Produce(String lock) {
        this.lock = lock;
      }

      public void setValue() {
        try {
          synchronized (lock) {
            if (!ValueObject.value.equals("")) {
              lock.wait();
            }
            String value = System.currentTimeMillis() + "_" + System.nanoTime();
            System.out.println("set的值是" + value);
            ValueObject.value = value;
            lock.notify();
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    /**
     * 消费者
     */
    static class Consume {
      private String lock;

      public Consume(String lock) {
        this.lock = lock;
      }

      public void getValue() {
        try {
          synchronized (lock) {
            if (ValueObject.value.equals("")) {
              lock.wait();
            }
            System.out.println("get的值是" + ValueObject.value);
            ValueObject.value = "";
            lock.notify();
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    static class ValueObject {
      public static String value = "";
    }
}

执行结果如下:

多生产者与多消费者

这种模式下,容易出现“假死”,也就是全部线程都进入了 WAITNG 状态,程序不在执行任何业务功能了,整个项目呈停止状态。

示例:

public class MultiProduceConsume {
  public static void main(String[] args) throws InterruptedException {
    String lock = new String("");
    Produce produce = new Produce(lock);
    Consume consume = new Consume(lock);
    Thread[] pThread = new Thread[2];
    Thread[] cThread = new Thread[2];
    for (int i = 0; i < 2; i++) {
      pThread[i] = new Thread(() -> {
        while (true) {
          produce.setValue();
        }
      }, "生产者" + (i + 1));

      cThread[i] = new Thread(() -> {
        while (true) {
          consume.getValue();
        }
      }, "消费者" + (i + 1));
      pThread[i].start();
      cThread[i].start();
    }

    Thread.sleep(5000);
    Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
    Thread.currentThread().getThreadGroup().enumerate(threadArray);
    for (int i = 0; i < threadArray.length; i++) {
      System.out.println(threadArray[i].getName() + " " + threadArray[i].getState());
    }
  }

  static class Produce {
    private String lock;

    public Produce(String lock) {
      this.lock = lock;
    }

    public void setValue() {
      try {
        synchronized (lock) {
          while(!ValueObject.value.equals("")) {
            System.out.println("生产者 " + Thread.currentThread().getName() + " WAITING了⭐");
            lock.wait();
          }
          System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了");
          String value = System.currentTimeMillis() + "_" + System.nanoTime();
          ValueObject.value = value;
          lock.notify();
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  static class Consume {
    private String lock;

    public Consume(String lock) {
      this.lock = lock;
    }

    public void getValue() {
      try {
        synchronized (lock) {
          while (ValueObject.value.equals("")) {
            System.out.println("消费者 " + Thread.currentThread().getName() + " WAITING了⭐");
            lock.wait();
          }
          System.out.println("消费者 " + Thread.currentThread().getName() + "RUNNABLE了");
          ValueObject.value = "";
          lock.notify();
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  static class ValueObject {
    public static String value = "";
  }
}

运行结果如图:

分析:

虽然代码中通过 wait/notify 进行通信了,但是不能保证 notify 唤醒的一定是异类,也可能是同类,比如“生产者”唤醒了“生产者”这样的情况。

解决方案

假死出现的主要原因是有可能连续唤醒了同类。所以解决方案很简单,就是把 notify() 改为 notifyAll() 即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Java实现简易生产者消费者模型过程解析,包括了Java实现简易生产者消费者模型过程解析的使用技巧和注意事项,需要的朋友参考一下 一、概述 一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程。当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完。 需要注意的是,有可能出现,停止生产产品后,消费者还没未来得及消费生产者生产的最后

  • 我已经使用Qt线程实现了生产者/消费者模式。多个生产者线程生成由消费者组合的数据。使用信号/时隙和排队连接实现通信。只要使用者能够比生产者线程更快地消耗数据,这就可以正常工作。 很难使我的代码缩放。特别是增加生产者的数量很容易,但很难产生一个以上的消费线程。 现在,当在具有许多内核的CPU/系统上运行软件时,问题就出现了。在这种情况下,我使用更多的线程来产生数据。有时会发生(取决于数据生成的复杂性

  • 本文向大家介绍Java如何通过线程解决生产者/消费者问题,包括了Java如何通过线程解决生产者/消费者问题的使用技巧和注意事项,需要的朋友参考一下 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示 生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生

  • 我有两个线程的问题,似乎没有正确同步。我基本上有一个布尔值名为“已占用”。当没有线程启动时,它被设置为false。但是当一个线程启动时,线程集被占用是真的,我有一个类,它有线程(run),它们调用下面的函数。 这是一个模拟银行的示例,它接收一个金额(初始余额),然后随机执行取款和存款。我的教授提到了一些关于从取款线程到存款线程的信号?这是怎么回事?在提取线程中,它应该运行到余额为2低,并等待存款线

  • 一、线程间通信的两种方式 1.wait()/notify() Object类中相关的方法有notify方法和wait方法。因为wait和notify方法定义在Object类中,因此会被所有的类所继承。这些方法都是final的,即它们都是不能被重写的,不能通过子类覆写去改变它们的行为。 ①wait()方法: 让当前线程进入等待,并释放锁。 ②wait(long)方法: 让当前线程进入等待,并释放锁,

  • 本文向大家介绍详解Python 模拟实现生产者消费者模式的实例,包括了详解Python 模拟实现生产者消费者模式的实例的使用技巧和注意事项,需要的朋友参考一下 详解Python 模拟实现生产者消费者模式的实例 散仙使用python3.4模拟实现的一个生产者与消费者的例子,用到的知识有线程,队列,循环等,源码如下: Python代码 在本例里面散仙启动了1个生产者线程,2个消费者线程,打印效果如下: