Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

yizhihongxing

下面是针对“Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解”的完整攻略。

什么是生产者消费者模式?

生产者消费者模式是指:生产者生产出来的任务放到一个仓库中,消费者从仓库中取出任务来消费。这样就将生产者和消费者融为一体,实现了解耦和。

生产者消费者模式需要解决的问题是:当仓库中的任务被消费完了,如何实现等待生产者生产新任务,同时也不影响已经在消费的消费者。

等待唤醒机制

在Java多线程中,使用wait()notify()notifyAll()方法等待唤醒机制实现线程之间的通信。

wait()方法的作用是:使当前线程进入等待状态,直到被唤醒。

notify()方法和notifyAll()方法的作用是:唤醒一个或多个等待的线程。

生产者消费者模式代码示例

下面是一个Java多线程之生产者消费者模式的代码示例。

任务类Task

public class Task {
    private int value;

    public Task(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

仓库类Storage

import java.util.LinkedList;

public class Storage {
    private final int MAX_SIZE = 5;
    private LinkedList<Task> tasks = new LinkedList<>();

    public synchronized void put(Task task) {
        while (tasks.size() == MAX_SIZE) {
            try {
                System.out.println("仓库已满,生产者" + Thread.currentThread().getName() + "进入等待状态");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("生产者" + Thread.currentThread().getName() + "生产了" + task.getValue() + "号商品");
        tasks.add(task);
        notifyAll();
    }

    public synchronized Task get() {
        while (tasks.size() == 0) {
            try {
                System.out.println("仓库为空,消费者" + Thread.currentThread().getName() + "进入等待状态");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        Task task = tasks.removeFirst();
        System.out.println("消费者" + Thread.currentThread().getName() + "消费了" + task.getValue() + "号商品");
        notifyAll();
        return task;
    }
}

生产者Producer类

public class Producer implements Runnable {
    private Storage storage;

    public Producer(Storage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            Task task = new Task(i);
            storage.put(task);
        }
    }
}

消费者Consumer类

public class Consumer implements Runnable {
    private Storage storage;

    public Consumer(Storage storage) {
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            Task task = storage.get();
        }
    }
}

测试类Test

public class Test {
    public static void main(String[] args) {
        Storage storage = new Storage();

        Producer producer1 = new Producer(storage);
        Producer producer2 = new Producer(storage);
        Consumer consumer1 = new Consumer(storage);
        Consumer consumer2 = new Consumer(storage);

        new Thread(producer1, "生产者1").start();
        new Thread(producer2, "生产者2").start();
        new Thread(consumer1, "消费者1").start();
        new Thread(consumer2, "消费者2").start();
    }
}

在上述代码示例中,Storage类是仓库类,Producer类是生产者类,Consumer类是消费者类,Task类是任务类,Test类是用于测试的主类。

运行测试类,输出内容如下:

仓库已满,生产者生产者1进入等待状态
生产者生产者2生产了1号商品
生产者生产者2生产了2号商品
生产者生产者1生产了3号商品
生产者生产者2生产了4号商品
生产者生产者1生产了5号商品
生产者生产者2进入等待状态
消费者消费者2消费了1号商品
消费者消费者1消费了2号商品
生产者生产者1生产了6号商品
生产者生产者2生产了7号商品
生产者生产者1生产了8号商品
生产者生产者2进入等待状态
消费者消费者1消费了3号商品
消费者消费者2消费了4号商品
生产者生产者1生产了9号商品
生产者生产者2生产了10号商品
仓库为空,消费者消费者2进入等待状态
消费者消费者1消费了5号商品
生产者生产者2生产了6号商品
生产者生产者1生产了7号商品
生产者生产者2生产了8号商品
生产者生产者1生产了9号商品
生产者生产者2进入等待状态
消费者消费者1消费了6号商品
消费者消费者2消费了7号商品
生产者生产者1生产了8号商品
生产者生产者2生产了9号商品
生产者生产者1生产了10号商品
消费者消费者2消费了8号商品
消费者消费者1消费了9号商品
消费者消费者2消费了10号商品

从输出内容中可以看出,生产者和消费者之间通过仓库进行线程通信,生产者不停地生产商品并放入仓库中,当仓库满时生产者进入等待状态,等待消费者消费商品后被唤醒;消费者不停地从仓库中取出商品并消费,当仓库为空时消费者进入等待状态,等待生产者生产商品后被唤醒。

以上是Java多线程之生产者消费者模式及等待唤醒机制代码详解,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 详解Java七大阻塞队列之SynchronousQueue

    详解Java七大阻塞队列之SynchronousQueue 简介 Java提供了七种不同类型的阻塞队列,SynchronousQueue是其中比较特殊的一种。它的特点是在插入元素时必须等待另外一个线程同时要移除这个元素,否则阻塞当前线程;同理,在移除元素时也必须等待另一个线程同时要插入这个元素,否则也会阻塞当前线程。这使得SynchronousQueue成为…

    多线程 2023年5月16日
    00
  • Java多线程并发编程(互斥锁Reentrant Lock)

    Java多线程并发编程(互斥锁Reentrant Lock)攻略 概述 在Java多线程编程中,为了保证多个线程并发执行时的安全性,我们需要使用同步控制。在Java中,synchronized关键字可以实现同步控制,但是它存在一些不足之处,比如它的锁只能是内置锁,无法进行灵活的控制和管理等。 为了解决这些问题,Java提供了一个更加灵活、功能更为强大的锁机制…

    多线程 2023年5月16日
    00
  • 易语言实现双线程的方法解析

    易语言实现双线程的方法解析 什么是双线程 双线程是指在一个程序中,可以有两个或以上的线程同时运行。在易语言编程中,实现双线程可以大大提高程序的效率。 实现双线程的方法 在易语言中,实现双线程的方法有两种:使用EasyThread库和使用Win32API。 使用EasyThread库 EasyThread库是易语言中自带的一个多线程库,通过它可以实现简单的多线…

    多线程 2023年5月17日
    00
  • C#多线程之线程通讯(AutoResetEvent)

    C#多线程之线程通讯(AutoResetEvent) 概述 在多线程中,线程之间的通讯是非常重要的一环。当一个线程处理完数据后,需要通知另一个线程来消费这个数据,这时候就需要线程通讯。C#中.NET框架提供两个线程通讯的类:- EventWaitHandle (ManualResetEvent和AutoResetEvent)- Monitor和lock 本文…

    多线程 2023年5月16日
    00
  • 一文带你了解Golang中的并发性

    一文带你了解Golang中的并发性 什么是Golang中的并发性 Golang作为一门现代化的编程语言,提供了同其他一些语言相似的多线程并发处理能力。Golang的并发机制使用一个叫做goroutine的轻量级协程来实现。Goroutine能够在一个Go程序中同时运行多个函数,而不用过多的耗费内存。 在Golang中,goroutine相对于其他线程的好处在…

    多线程 2023年5月17日
    00
  • hadoop map-reduce中的文件并发操作

    关于”Hadoop Map-Reduce 中的文件并发操作”,我会给您提供以下完整攻略: 1. 背景知识 在 Hadoop 的 Map-Reduce 程序中,文件是作为输入和输出的主要载体。而在实际的应用场景中,由于对大数据处理的需求,经常会存在多个任务同时对同一文件进行读/写操作的情况,这时候不可避免地会出现文件的并发访问问题。为了避免出现因为并发访问而导…

    多线程 2023年5月16日
    00
  • python多线程semaphore实现线程数控制的示例

    下面我将为您详细讲解如何使用Python多线程Semaphore实现线程数控制。 什么是Semaphore Semaphore是一种并发控制机制,用于控制同时访问特定资源的线程数量。Semaphore维护一个内部计数器,该计数器表示可用资源的数量。当一个线程需要访问资源时,它先要向Semaphore请求许可,Semaphore会将计数器减1,然后线程可以访问…

    多线程 2023年5月17日
    00
  • MySQL系列之十 MySQL事务隔离实现并发控制

    MySQL事务隔离实现并发控制是MySQL数据库中非常重要的一个功能,它能够实现对并发事务的隔离,避免出现并发访问数据库时的数据一致性问题。本文将为读者介绍MySQL事务隔离的基本概念、实现方式及其使用方法。 MySQL事务隔离的基本概念 MySQL事务隔离是指通过数据库隔离等级(Isolation Level)来实现多个并发事务间互不影响的机制。在MySQ…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部