Java多种方式实现生产者消费者模式

实现生产者消费者模式是 Java 多线程编程中的一个重要概念。在多线程环境下,生产者和消费者可以并行执行,提高了程序的效率。这里将详细讲解 Java 多种方式实现生产者消费者模式的完整攻略。

1. 管程法

管程法是最常用的实现生产者消费者模式的方法之一。它要求生产者和消费者共享同一个缓冲区,由缓冲区提供同步的方法供生产者和消费者调用。

以下是管程法的实现示例代码:

public class Buffer {
    private int data;
    private boolean empty = true;

    public synchronized int get() {
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        empty = true;
        notifyAll();
        return data;
    }

    public synchronized void put(int data) {
        while (!empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        empty = false;
        this.data = data;
        notifyAll();
    }
}

public class Producer extends Thread {
    private Buffer buffer;

    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            buffer.put(i);
            System.out.println("Producer put: " + i);
            try {
                sleep((int)(Math.random() * 100));
            } catch (InterruptedException e) {}
        }
    }
}

public class Consumer extends Thread {
    private Buffer buffer;

    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            int data = buffer.get();
            System.out.println("Consumer get: " + data);
            try {
                sleep((int)(Math.random() * 100));
            } catch (InterruptedException e) {}
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);
        producer.start();
        consumer.start();
    }
}

2. 信号量法

信号量法是另一种实现生产者消费者模式的方法,它使用了信号量机制对临界区资源进行同步控制。

以下是信号量法的实现示例代码:

public class Buffer {
    private int data;
    private Semaphore mutex = new Semaphore(1);
    private Semaphore full = new Semaphore(0);
    private Semaphore empty;

    public Buffer(int size) {
        empty = new Semaphore(size);
    }

    public void get() throws InterruptedException {
        full.acquire();
        mutex.acquire();
        System.out.println(Thread.currentThread().getName() +
                           " Consumer get: " + data);
        Thread.sleep((int)(Math.random() * 100));
        mutex.release();
        empty.release();
    }

    public void put(int data) throws InterruptedException {
        empty.acquire();
        mutex.acquire();
        this.data = data;
        System.out.println(Thread.currentThread().getName() +
                           " Producer put: " + data);
        Thread.sleep((int)(Math.random() * 100));
        mutex.release();
        full.release();
    }
}

public class Producer extends Thread {
    private Buffer buffer;

    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                buffer.put(i);
            } catch (InterruptedException e) {}
        }
    }
}

public class Consumer extends Thread {
    private Buffer buffer;

    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                buffer.get();
            } catch (InterruptedException e) {}
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(5);
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);
        producer.start();
        consumer.start();
    }
}

以上代码演示了信号量法的实现过程,在实现时,我们需要使用 Semaphore 类创建互斥量和信号量对象,调用其 acquire() 和 release() 方法实现同步控制和线程阻塞。

综上所述,通过管程法和信号量法我们可以实现 Java 的生产者消费者模式。我们只需要根据自己的需求合理选择适合的方法即可。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多种方式实现生产者消费者模式 - Python技术站

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

相关文章

  • 解决IDEA springboot”spring-boot-maven-plugin”报红问题

    首先,这个报红问题通常是由于IntelliJ IDEA的缓存导致的,因此我们可以尝试清除缓存解决这个问题。 步骤如下: 在IntelliJ IDEA中打开你的项目,进入Maven Projects的面板。 找到被报红的项目,展开该项目的”Plugins”节点。 找到“spring-boot-maven-plugin”这个插件,右键选择“clean”,然后再右…

    Java 2023年5月19日
    00
  • 图文详解Java中的字节输入与输出流

    图文详解Java中的字节输入与输出流 什么是字节输入与输出流 在Java中,一个流就是一种数据传输方式。流分为字节流和字符流两种类型。字节输入流和输出流是Java中的一种字节流,主要用于读取和写入字节数据。 既然是字节数据,那么我们可以理解成Java中所有的数据最终都要用二进制的形式进行存储,而字节流就是能够读入/写出(input/output)这些二进制数…

    Java 2023年5月26日
    00
  • java字符串求并集的方法

    针对这个问题,我会给出详细的解释和两个示例。 Java字符串求并集的方法 一、使用Java的Set集合 Java的Set集合是不重复的集合,很适合用来进行字符串的并集操作。具体的实现方式是创建两个Set集合,分别用来存储两个字符串的字符,然后将两个集合进行合并,最后输出合并后的结果即可。 下面是示例代码: import java.util.HashSet; …

    Java 2023年5月27日
    00
  • Java中删除文件或文件夹的几种方法总结

    让我来为你详细讲解“Java中删除文件或文件夹的几种方法总结”这个话题。 简介 在Java中,我们可以使用各种方法来删除文件或者文件夹。本文将总结出最常用的几种方式。 方法一:File类的delete()方法 我们可以使用Java中的File类的delete()方法来删除一个单独的文件,如下所示: File file = new File("pat…

    Java 2023年5月20日
    00
  • Java毕业设计实战之校园一卡通系统的实现

    Java毕业设计实战之校园一卡通系统的实现 系统实现的功能点 学生的基本信息管理(包括学生信息的录入、查询、修改和删除); 学生校园卡的管理(包括校园卡的发放、挂失、充值和注销); 学生消费记录管理(包括消费记录的录入、查询和统计); 管理员权限管理(包括管理员的新增、修改、删除和查询); 系统日志管理(包括系统操作日志和异常日志的记录和查询); 系统安全性…

    Java 2023年5月24日
    00
  • 使用maven如何将项目中的test代码打包进jar中

    使用 Maven 将项目中的 test 代码打包进 jar 中,可以实现在发布项目时一并发布 test 代码,方便其他人也能进行测试。下面是具体的步骤: 在 pom.xml 文件中添加以下代码,指定将 test 代码打包进 jar 中: <build> <plugins> <plugin> <groupId>o…

    Java 2023年5月20日
    00
  • Spark SQL常见4种数据源详解

    Spark SQL常见4种数据源详解 Spark SQL是一个强大的分布式数据处理引擎,可以对多种数据源进行处理。本文将重点讲解Spark SQL常见的4种数据源,包括Hive、JSON、Parquet和JDBC,并附带示例说明。 1. Hive Hive是Hadoop的数据仓库,Spark可以使用Hive的数据进行处理。为了使用Hive,请按照以下步骤: …

    Java 2023年6月16日
    00
  • Java中的函数重载是什么?

    函数重载(Overloading)指的是在同一个类中定义的多个函数具有相同名称但参数列表不同的情况。同名函数的不同实现方法称为函数重载。Java方法重载时,首先形参类型必须不同,其次形参个数也必须不同,还需要注意当形参类型或个数相同时必须有不同的形参顺序。 Java中的函数重载有以下几个特点: 函数名称相同,但函数参数不同。 函数的返回类型可以相同也可以不同…

    Java 2023年4月27日
    00
合作推广
合作推广
分享本页
返回顶部