经典 生产者-消费者线程【操作系统】

简介: 经典 生产者-消费者线程【操作系统】

问题描述

实现经典同步问题:生产者—消费者,具体要求如下:

① 一个大小为 n的缓冲区,初始状态为空。

② 生产者: 往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据之后再添加

③ 消费者: 从缓冲区中读取数据,若缓冲区为空,等待生产者添加数据之后再读取
下面为java代码实现

设定

  • n赋值为10
static final int n=10;
  • 往缓冲区中添加的数据为buffer[in]的下标in
 buffer[in]= ""+in;

简单实现

package os.prioducer_consumer;
import java.util.concurrent.Semaphore;
public class ProcessTest1 {
    static final int n=10;
    static int in=0,out=0;
    static String[] buffer=new String[n];
    static Semaphore mutex=new Semaphore(1,false);
    static Semaphore empty=new Semaphore(n,false);
    static Semaphore full=new Semaphore(0,false);
    public static void main(String[] args) {
        Thread producer=new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        empty.acquire();
                        mutex.acquire();
                        System.out.println(Thread.currentThread().getName()+"放入"+in);
                        buffer[in]= ""+in;
                        in=(in+1)%n;
                        Thread.sleep(1000);//休眠表示放入的过程
                        mutex.release();
                        full.release();
                    }catch (InterruptedException e) {
                        System.out.println("生产者获取资源失败!");
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread consumer=new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        full.acquire();
                        mutex.acquire();
                        String o=buffer[out];
                        System.out.println(Thread.currentThread().getName()+"取出"+o);
                        Thread.sleep(1000);//休眠表示放入的过程
                        out=(out+1)%n;
                        mutex.release();
                        empty.release();
                    }catch (InterruptedException e) {
                        System.out.println("消费者获取资源失败!");
                        e.printStackTrace();
                    }
                }
            }
        });
        producer.setName("producer");
        consumer.setName("consumer");
        producer.start();
        consumer.start();
    }
}

运行结果

producer放入0
producer放入1
producer放入2
producer放入3
producer放入4
producer放入5
consumer取出0
consumer取出1
consumer取出2
consumer取出3
consumer取出4
consumer取出5
producer放入6
producer放入7
producer放入8
consumer取出6
consumer取出7
consumer取出8
producer放入9
producer放入0
consumer取出9
producer放入1
producer放入2
producer放入3
producer放入4
producer放入5
producer放入6
producer放入7
consumer取出0
consumer取出1
producer放入8

如果需要增加生产者和消费者的数量,只能复制一份,增加变量,比较麻烦
所以,下面封装为类。

    Thread producer1=new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        empty.acquire();
                        mutex.acquire();
                        System.out.println(Thread.currentThread().getName()+"放入"+in);
                        buffer[in]= ""+in;
                        in=(in+1)%n;
                        Thread.sleep(1000);//休眠表示放入的过程
                        mutex.release();
                        full.release();
                    }catch (InterruptedException e) {
                        System.out.println("生产者获取资源失败!");
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread consumer1=new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        full.acquire();
                        mutex.acquire();
                        String o=buffer[out];
                        System.out.println(Thread.currentThread().getName()+"取出"+o);
                        Thread.sleep(1000);//休眠表示放入的过程
                        out=(out+1)%n;
                        mutex.release();
                        empty.release();
                    }catch (InterruptedException e) {
                        System.out.println("消费者获取资源失败!");
                        e.printStackTrace();
                    }
                }
            }
        });
        producer1.setName("producer1");
        consumer1.setName("consumer1");
        producer1.start();
        consumer1.start();

运行结果

producer放入0
producer放入1
producer放入2
producer放入3
producer放入4
producer放入5
producer放入6
producer放入7
producer放入8
producer1放入9
consumer取出0
consumer取出1
consumer取出2
consumer取出3
consumer取出4
consumer取出5
consumer取出6
consumer1取出7
producer放入0
producer放入1
producer放入2
producer1放入3
consumer取出8
consumer1取出9
consumer1取出0
consumer1取出1

封装为类和对象

package os.prioducer_consumer;
import java.util.concurrent.Semaphore;
class MyProcess {
    static final int n=5;
    static int in = 0, out = 0;
    static String[] buffer = new String[n];
    static Semaphore mutex = new Semaphore(1, false);
    static Semaphore empty = new Semaphore(n, false);
    static Semaphore full = new Semaphore(0, false);
    public void producerFunc() {
        try {
            empty.acquire();
            mutex.acquire();
            System.out.println(Thread.currentThread().getName()+"放入" + in);
            buffer[in] = "" + in;
            in = (in + 1) % n;
            Thread.sleep(1000);//休眠表示放入的过程
            mutex.release();
            full.release();
        } catch (InterruptedException e) {
            System.out.println("生产者获取资源失败!");
            e.printStackTrace();
        }
    }
    public void consumerFunc() {
        try {
            full.acquire();
            mutex.acquire();
            String o = buffer[out];
            System.out.println(Thread.currentThread().getName()+"取出" + o);
            Thread.sleep(1000);//休眠表示放入的过程
            out = (out + 1) % n;
            mutex.release();
            empty.release();
        } catch (InterruptedException e) {
            System.out.println("消费者获取资源失败!");
            e.printStackTrace();
        }
    }
}
class Producer extends Thread {
    private MyProcess myProcess;
    public Producer(MyProcess myProcess) {
        this.myProcess = myProcess;
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myProcess.producerFunc();
        }
    }
}
class Consumer extends Thread{
    private MyProcess myProcess;
    public Consumer(MyProcess myProcess) {
        this.myProcess = myProcess;
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            myProcess.consumerFunc();
        }
    }
}
public class ProcessTest2 {
    public static void main(String[] args) {
        MyProcess myProcess=new MyProcess();
        Producer producer = new Producer(myProcess);
        Producer producer1 = new Producer(myProcess);
        Consumer consumer = new Consumer(myProcess);
        Consumer consumer1 = new Consumer(myProcess);
        producer.setName("producer");
        producer1.setName("producer1");
        consumer.setName("consumer");
        consumer1.setName("consumer1");
        producer.start();
        producer1.start();
        consumer.start();
        consumer1.start();
    }
}

运行结果

producer放入0
producer1放入1
consumer1取出0
producer放入2
consumer取出1
producer1放入3
consumer取出2
consumer1取出3
producer放入4
producer1放入5
consumer取出4
producer放入6
consumer1取出5
producer1放入7
consumer取出6
producer放入8
consumer1取出7
producer1放入9
consumer取出8
producer放入0
consumer1取出9
producer1放入1
consumer取出0
producer放入2
consumer1取出1
producer1放入3
consumer取出2

如果需要增加生产者和消费者的数量,只能需新建变量即可

    Producer producer1 = new Producer(myProcess);
        Consumer consumer1 = new Consumer(myProcess);
        producer1.setName("producer1");
        consumer1.setName("consumer1");
        producer1.start();
        consumer1.start();
相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
3天前
|
算法 调度 开发者
深入理解操作系统:进程与线程的管理
在数字世界的复杂编织中,操作系统如同一位精明的指挥家,协调着每一个音符的奏响。本篇文章将带领读者穿越操作系统的幕后,探索进程与线程管理的奥秘。从进程的诞生到线程的舞蹈,我们将一起见证这场微观世界的华丽变奏。通过深入浅出的解释和生动的比喻,本文旨在揭示操作系统如何高效地处理多任务,确保系统的稳定性和效率。让我们一起跟随代码的步伐,走进操作系统的内心世界。
|
26天前
|
Linux 调度 C语言
深入理解操作系统:进程和线程的管理
【10月更文挑战第32天】本文旨在通过浅显易懂的语言和实际代码示例,带领读者探索操作系统中进程与线程的奥秘。我们将从基础知识出发,逐步深入到它们在操作系统中的实现和管理机制,最终通过实践加深对这一核心概念的理解。无论你是编程新手还是希望复习相关知识的资深开发者,这篇文章都将为你提供有价值的见解。
|
28天前
深入理解操作系统:进程与线程的管理
【10月更文挑战第30天】操作系统是计算机系统的核心,它负责管理计算机硬件资源,为应用程序提供基础服务。本文将深入探讨操作系统中进程和线程的概念、区别以及它们在资源管理中的作用。通过本文的学习,读者将能够更好地理解操作系统的工作原理,并掌握进程和线程的管理技巧。
39 2
|
1月前
|
调度 Python
深入浅出操作系统:进程与线程的奥秘
【10月更文挑战第28天】在数字世界的幕后,操作系统悄无声息地扮演着关键角色。本文将拨开迷雾,深入探讨操作系统中的两个基本概念——进程和线程。我们将通过生动的比喻和直观的解释,揭示它们之间的差异与联系,并展示如何在实际应用中灵活运用这些知识。准备好了吗?让我们开始这段揭秘之旅!
|
2月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
20 1
|
2月前
|
算法 安全 调度
深入理解操作系统:进程与线程的管理
【10月更文挑战第9天】在数字世界的心脏跳动着的,不是别的,正是操作系统。它如同一位无形的指挥家,协调着硬件与软件的和谐合作。本文将揭开操作系统中进程与线程管理的神秘面纱,通过浅显易懂的语言和生动的比喻,带你走进这一复杂而又精妙的世界。我们将从进程的诞生讲起,探索线程的微妙关系,直至深入内核,理解调度算法的智慧。让我们一起跟随代码的脚步,解锁操作系统的更多秘密。
38 1
|
1月前
|
Linux 调度
探索操作系统核心:进程与线程管理
【10月更文挑战第24天】在数字世界的心脏,操作系统扮演着至关重要的角色。它不仅是计算机硬件与软件之间的桥梁,更是管理和调度资源的大管家。本文将深入探讨操作系统的两大基石——进程与线程,揭示它们如何协同工作以确保系统运行得井井有条。通过深入浅出的解释和直观的代码示例,我们将一起解锁操作系统的管理奥秘,理解其对计算任务高效执行的影响。
|
2月前
|
算法 调度 UED
探索操作系统中的多线程编程
【8月更文挑战第78天】在数字世界的复杂迷宫中,操作系统扮演着至关重要的角色。本文旨在揭开操作系统中多线程编程的神秘面纱,引导读者理解其概念、实现及应用。通过深入浅出的方式,我们将探讨如何在程序设计中运用多线程,以及这一技术如何优化软件性能和提升用户体验。文章将结合具体代码示例,展示多线程在实际应用中的魔力。无论你是编程新手还是资深开发者,这篇文章都将为你提供新的视角和思考路径。
|
2月前
|
消息中间件 NoSQL 关系型数据库
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
25 0
|
28天前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
47 0
Vanilla OS:下一代安全 Linux 发行版

热门文章

最新文章