本文将介绍如何在 Windows 操作系统下,使用 Java 语言,采用进程(线程)同步和互斥的技术编写程序实现生产者-消费者问题,并书写界面图形化的代码。由于题目中没有明确要求使用哪种图形化界面编程工具,因此本篇答案将使用 Java Swing 编写图形化界面的代码。

首先,我们需要定义一个共享缓冲区,用于生产者和消费者之间的数据交换。假设缓冲区的大小为 10,定义如下:

public class Buffer {
    private int[] buffer;
    private int size;
    private int in; // 生产者写入位置
    private int out; // 消费者读取位置
    private int count; // 缓冲区中的数据数量

    public Buffer(int size) {
        this.buffer = new int[size];
        this.size = size;
        this.in = 0;
        this.out = 0;
        this.count = 0;
    }

    public synchronized void put(int data) throws InterruptedException {
        while (count == size) { // 缓冲区已满,等待消费者读取
            wait();
        }
        buffer[in] = data;
        in = (in + 1) % size;
        count++;
        notifyAll(); // 通知消费者可以读取数据了
    }

    public synchronized int get() throws InterruptedException {
        while (count == 0) { // 缓冲区为空,等待生产者写入
            wait();
        }
        int data = buffer[out];
        out = (out + 1) % size;
        count--;
        notifyAll(); // 通知生产者可以写入数据了
        return data;
    }
}

其中,put 方法表示生产者往缓冲区中写入数据,get 方法表示消费者从缓冲区中读取数据。这两个方法都使用了 synchronized 关键字,实现了进程(线程)同步和互斥。

接下来,我们需要编写生产者和消费者的代码。这里我们定义一个 Producer 类和一个 Consumer 类,它们都需要访问缓冲区。代码如下:

public class Producer implements Runnable {
    private Buffer buffer;

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

    public void run() {
        try {
            for (int i = 0; i < 100; i++) {
                buffer.put(i);
                Thread.sleep((int) (Math.random() * 100));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Consumer implements Runnable {
    private Buffer buffer;

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

    public void run() {
        try {
            while (true) {
                int data = buffer.get();
                System.out.println(data);
                Thread.sleep((int) (Math.random() * 100));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

最后,我们需要编写图形化界面的代码。这里我们使用 Java Swing 库,创建一个窗口,包含一个文本框和一个按钮。点击按钮后,启动一个新的线程作为生产者,同时在文本框中显示生产者的状态。点击另一个按钮后,启动一个新的线程作为消费者,同时在文本框中显示消费者的状态。代码如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MainFrame extends JFrame {
    private JTextArea textArea;
    private JButton producerButton;
    private JButton consumerButton;
    private Buffer buffer;

    public MainFrame() {
        super('生产者消费者问题');

        buffer = new Buffer(10);

        textArea = new JTextArea(10, 30);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);

        producerButton = new JButton('启动生产者');
        producerButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Producer producer = new Producer(buffer);
                Thread thread = new Thread(producer);
                thread.start();
                textArea.append('启动生产者线程\n');
            }
        });

        consumerButton = new JButton('启动消费者');
        consumerButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Consumer consumer = new Consumer(buffer);
                Thread thread = new Thread(consumer);
                thread.start();
                textArea.append('启动消费者线程\n');
            }
        });

        JPanel panel = new JPanel();
        panel.add(producerButton);
        panel.add(consumerButton);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(scrollPane, BorderLayout.CENTER);
        contentPane.add(panel, BorderLayout.SOUTH);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    public static void main(String[] args) {
        new MainFrame();
    }
}

运行程序后,可以点击“启动生产者”和“启动消费者”按钮,观察生产者和消费者的状态,验证生产者消费者问题的解决方案。

Java 实现生产者消费者问题:线程同步与互斥、图形化界面

原文地址: https://www.cveoy.top/t/topic/nG3h 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录