Fork me on GitHub

生产者和消费者问题java代码实现

上机实验(老师的代码很好~)

一、 实验任务

问题描述:考虑有一些生产者和消费者进程,生产者进程生产信息并把它们放入缓冲池中,消费者从缓冲池中取走信息。生产者—消费者问题是相互合作的进程关系的一种抽象,如在输入时,输入进程是生产者,计算进程是消费者;而在输出时,则计算进程是生产者,打印进程是消费者。请使用信号量机制来解决生产者—消费者问题。

 互斥关系:

I)设缓冲池有n个单元。

II)当n个单元装满时,生产者必须等待。

III)当缓冲池空时,消费者必须等待。

二、实验目的

1. 加深对进程概念的理解,明确进程和程序的区别。

2. 进一步认识并发执行的实质。

3. 验证用信号量机制实现进程互斥的方法。

4. 验证用信号机制实现进程同步的方法。

三、实验环境

1. 一台运行Windows 7操作系统的计算机。

2. 选用以CC++visual c++Java等任何一种语言。

四、实验要求

在程序编制中,应有数据显示,最好采用图形界面显示。

生产者和消费者的进程采用程序模拟的方法运行。

五、实验准备知识

1. 阅读课本有关进程管理以及进程同步的有关章节,对临界区和临界资源概念要清晰,充分理解信号信号量机制。

2. 阅读几种经典进程同步问题的算法并理解。熟练掌握生产者—消费者的算法思想。

 

Buffers类

 

import javax.swing.JTextArea;  /** 定义临界资源:缓冲队列 * */ 

public class Buffers {
    JTextArea ta;
    static final int productBufferNum = 2; // 缓冲单元数
    ProductBuffer pBuffer[] = new ProductBuffer[productBufferNum]; // 缓冲队列
    int in = 0; // 缓冲单元指针,用于放产品
    int out = 0; // 缓冲单元指针,用于取产品
    int consumeProductNo; // 记录消费产品的编号
    int usedBufferNum = 0; // 记录缓冲队列已使用的缓冲单元个数

    public Buffers(JTextArea ta) {
        this.ta = ta;
        // 初始化
        for (int j = 0; j < productBufferNum; j++) {
            pBuffer[j] = new ProductBuffer();
        }
        for (int i = 0; i < productBufferNum; i++) {
            pBuffer[i].product = -1;
            pBuffer[i].hasProduct = false;
        }
    }

    // 取产品
    public synchronized void get(int id) { // 缓冲队列空则等待
        if (usedBufferNum == 0) {
            try {
                super.wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        consumeProductNo = pBuffer[out].product; // 取出产品
        pBuffer[out].product = 0; // 清空缓冲单元
        pBuffer[out].hasProduct = false; // 置"无产品"标识
        usedBufferNum--; // 输出本次取产品后缓冲队列的情况
        ta.append("消费者" + id + "将产品" + consumeProductNo + "从缓冲单元" + out
                + "取出,缓冲队列状态如下:\n");
        printBuffer();
        out = (out + 1) % productBufferNum; // 更新指针
        // 唤醒等待线程
        super.notify();
    }

    // 放产品
    public synchronized void put(int productNo, int id) { // 缓冲队列满则等待
        if (usedBufferNum == productBufferNum) {
            try {
                super.wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        pBuffer[in].product = productNo; // 放产品
        pBuffer[in].hasProduct = true; // 置“有产品”标识
        usedBufferNum++; // /输出本次放入产品后,缓冲队列的情况
        ta.append("生产者" + id + "将产品" + productNo + "放入缓冲单元" + in
                + ",缓冲队列状态如下:\n");
        printBuffer();
        in = (in + 1) % productBufferNum; // 更新指针
        // 唤醒等待线程
        super.notify();
    }

    // 打印缓冲队列当前情况
    private void printBuffer() {
        ta.append("缓冲单元编号             产品编号        缓冲单元状态\n");
        for (int i = 0; i < productBufferNum; i++) {
            ta.append("\t" + i + "\t" + pBuffer[i].product + "\t"
                    + pBuffer[i].hasProduct + "\n");
        }
    }
}

 

 

ProductBuffer类

/* 一个缓冲单元 */ 
public class ProductBuffer {
    int product; //存放产品编号  
    boolean hasProduct; //标识该缓冲区是否有产品,true有产品,false无产品 
}

 

ProcuctConsumerMain类

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; import java.awt.event.ActionListener;  
import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; 
import javax.swing.JScrollPane; import javax.swing.JTextArea;  
/** 生产者消费者问题实现(可以有多个生产者消费者)  **/ 

public class ProducerConsumerMain implements ActionListener {
    boolean isRun = true; //用于控制线程结束  
    JTextArea ta = new JTextArea();
    Buffers buffers = new Buffers(ta); //缓冲队列   
    static final int producerNum = 8; //生产者个数  
    static final int consumerNum = 2; //消费者个数    
    ProducerThread proThread[] = new ProducerThread[producerNum];
    ConsumerThread conThread[] = new ConsumerThread[consumerNum];
    Thread producer[] = new Thread[producerNum];
    Thread consumer[] = new Thread[consumerNum];

    public ProducerConsumerMain() {
        createUI(); //创建界面      
        //创建多个生产者和消费者线程并开始执行   
        for (int i = 0; i < producerNum; i++) {
            proThread[i] = new ProducerThread(i + 1);
            producer[i] = new Thread(proThread[i]);
            producer[i].start();
        }
        for (int j = 0; j < consumerNum; j++) {
            conThread[j] = new ConsumerThread(j + 1);
            consumer[j] = new Thread(conThread[j]);
            consumer[j].start();
        }
    }

    //创建界面 
    public void createUI() {
        JFrame frame = new JFrame("生产者消费者");
        JPanel panel = new JPanel(new BorderLayout());
        JScrollPane scrPane = new JScrollPane(ta);
        panel.add(scrPane, BorderLayout.CENTER);
        JButton button = new JButton("停止");
        button.addActionListener(this);
        panel.add(button, BorderLayout.SOUTH);
        frame.add(panel);
        frame.setVisible(true);
        frame.setSize(1000, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    //按钮响应事件 
    public void actionPerformed(ActionEvent e) {
        isRun = false;
        //控制线程结束   
        System.out.println("停止");
    }

    public static void main(String args[]) {
        ProducerConsumerMain producerConsumer = new ProducerConsumerMain();
    }

    //定义生产者线程 
    class ProducerThread implements Runnable {
        int productNo = 0; //产品编号   
        int id; //生产者ID      

        public ProducerThread(int id) {
            this.id = id;
        }

        public void run() {
            while (isRun) {
                productNo++; //生产产品     
                buffers.put(productNo, id); //将产品放入缓冲队列     
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //定义消费者线程  
    class ConsumerThread implements Runnable {
        int id; //消费者ID   

        public ConsumerThread(int id) {
            this.id = id;
        }

        public void run() {
            while (isRun) {
                buffers.get(id); //从缓冲队列中取出产品     
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

运行界面

 

posted @ 2018-10-15 20:07  &#127808;&#127808;&#127808;  阅读(1685)  评论(0编辑  收藏  举报
🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀 🍀