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日

相关文章

  • Java获取字符串编码格式实现思路

    获取Java字符串的编码格式可以通过以下步骤来实现: 将字符串转换为字节流 通过分析字节流来确定编码格式 下面展示两个示例: 示例一:使用系统默认编码获取字符串编码格式 String str = "你好,世界!"; byte[] bytes = str.getBytes(); // 将字符串转换为字节流 Charset charset =…

    Java 2023年5月20日
    00
  • Java开发学习之Bean的作用域和生命周期详解

    Java开发学习之Bean的作用域和生命周期详解 在Java开发中,Bean(Java Bean)是一种可以重复使用的Java类,它具有可重用性和组件性,通常用于构建Java Web应用程序。在使用Bean时,了解Bean的作用域和生命周期是至关重要的,下面我们将详细讲解Bean的作用域和生命周期,帮助初学者更好地理解并使用Bean。 一、Bean的作用域 …

    Java 2023年5月26日
    00
  • Java 关于时间复杂度和空间复杂度的深度刨析

    Java 关于时间复杂度和空间复杂度的深度刨析 时间复杂度和空间复杂度是算法中非常重要的概念,它们可以帮助我们衡量算法的效率。本文将对它们进行深度探讨,并用实例进行说明。 时间复杂度 时间复杂度是指算法执行所需要的时间,通常使用O(n)表示,其中n是输入数据的规模。常见的时间复杂度有: 常数时间复杂度:O(1),无论输入数据量的大小,算法的执行时间都保持不变…

    Java 2023年5月26日
    00
  • SpringBoot Application注解原理及代码详解

    SpringBootApplication注解原理及代码详解 1. Spring Boot介绍 ​ Spring Boot是一个应用于快速创建基于Spring框架的应用程序的工具。它大大简化了Spring应用程序的搭建和开发流程, 十分适合用于微服务开发等快速迭代的场景。 2. SpringBootApplication注解 ​ SpringBootAppl…

    Java 2023年5月15日
    00
  • 启用springboot security后登录web页面需要用户名和密码的解决方法

    启用 SpringBoot Security 后登录 Web 页面需要用户名和密码的解决方法主要涉及到如何添加用户和授权认证的过程。 添加用户 可以通过在 application.yml 文件中配置用户名和密码来添加用户: spring: security: user: name: admin # 用户名 password: password # 密码 ro…

    Java 2023年5月20日
    00
  • MyBatis批量插入(insert)数据操作

    让我来详细讲解一下MyBatis批量插入数据操作的攻略。 一、什么是批量插入 批量插入指在一次数据库操作中插入多条数据记录。相比于循环单次插入,批量插入可以显著提高数据库操作效率。 二、MyBatis批量插入的实现方式 在MyBatis中,可以通过insert标签或者selectKey标签实现批量插入。 1. insert标签实现批量插入 使用insert标…

    Java 2023年5月20日
    00
  • cmd中javac和java使用及注意事项详解

    当我们需要开发Java程序时,需要使用到JDK提供的工具 javac 和 java。其中 javac 是用于编译Java源代码生成二进制字节码文件,而 java 则是用于运行已经编译好的二进制字节码文件,下面详细介绍一下在cmd中使用javac和java的方法及注意事项。 1. 安装JDK并配置环境变量 在使用javac和java之前,首先需要安装JDK并配…

    Java 2023年5月23日
    00
  • springboot整合dubbo设置全局唯一ID进行日志追踪的示例代码

    下面就是 “springboot整合dubbo设置全局唯一ID进行日志追踪的示例代码” 的详细攻略。 先了解基本概念 在介绍示例代码之前,先了解一下基本概念,有助于更好地理解实现过程: Dubbo:一种高性能、轻量级的远程服务框架,支持 RPC 协议和多种注册中心。 TraceId:一条调用链路的唯一标识,常用于日志追踪,用于串联业务流程的各个步骤。 MDC…

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