生產者和消費者問題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();
                }
            }
        }
    }
}

 

運行界面

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM