Java图形界面多线程消费系统详细代码加讲解
时间: 2023-12-23 13:02:26 浏览: 84
下面是一个简单的 Java 图形界面多线程消费系统的详细代码和讲解:
```java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MultiThreadConsumerSystem extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JButton startButton, stopButton;
private JLabel[] productLabels, consumerLabels;
private JTextField[] productTextFields, consumerTextFields;
private JTextArea messageArea;
private JScrollPane messageScrollPane;
private JPanel productPanel, consumerPanel, buttonPanel;
private Thread[] productThreads, consumerThreads;
private boolean stopFlag;
private int bufferSize, productNum, consumerNum;
private Buffer buffer;
public MultiThreadConsumerSystem() {
setTitle("Java 多线程消费系统");
setSize(600, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initGUI();
}
private void initGUI() {
// 产品区域
productPanel = new JPanel(new GridLayout(0, 2));
productLabels = new JLabel[3];
productLabels[0] = new JLabel("缓冲区大小:");
productLabels[1] = new JLabel("生产者数量:");
productLabels[2] = new JLabel("产品数量:");
productTextFields = new JTextField[3];
productTextFields[0] = new JTextField(10);
productTextFields[0].setText("10");
productTextFields[1] = new JTextField(10);
productTextFields[1].setText("3");
productTextFields[2] = new JTextField(10);
productTextFields[2].setText("20");
for (int i = 0; i < 3; i++) {
productPanel.add(productLabels[i]);
productPanel.add(productTextFields[i]);
}
// 消费者区域
consumerPanel = new JPanel(new GridLayout(0, 2));
consumerLabels = new JLabel[1];
consumerLabels[0] = new JLabel("消费者数量:");
consumerTextFields = new JTextField[1];
consumerTextFields[0] = new JTextField(10);
consumerTextFields[0].setText("5");
consumerPanel.add(consumerLabels[0]);
consumerPanel.add(consumerTextFields[0]);
// 按钮区域
buttonPanel = new JPanel(new FlowLayout());
startButton = new JButton("开始");
startButton.addActionListener(this);
stopButton = new JButton("停止");
stopButton.addActionListener(this);
buttonPanel.add(startButton);
buttonPanel.add(stopButton);
// 消息区域
messageArea = new JTextArea(10, 50);
messageArea.setEditable(false);
messageArea.setLineWrap(true);
messageScrollPane = new JScrollPane(messageArea);
// 将各个组件添加到窗口中
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(productPanel, BorderLayout.NORTH);
contentPane.add(consumerPanel, BorderLayout.CENTER);
contentPane.add(buttonPanel, BorderLayout.SOUTH);
contentPane.add(messageScrollPane, BorderLayout.EAST);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == startButton) {
stopFlag = false;
bufferSize = Integer.parseInt(productTextFields[0].getText());
productNum = Integer.parseInt(productTextFields[1].getText());
consumerNum = Integer.parseInt(consumerTextFields[0].getText());
buffer = new Buffer(bufferSize, messageArea);
// 创建生产者线程和消费者线程
productThreads = new Thread[productNum];
consumerThreads = new Thread[consumerNum];
for (int i = 0; i < productNum; i++) {
productThreads[i] = new ProductThread(i + 1, buffer, messageArea);
}
for (int i = 0; i < consumerNum; i++) {
consumerThreads[i] = new ConsumerThread(i + 1, buffer, messageArea);
}
// 启动生产者线程和消费者线程
for (int i = 0; i < productNum; i++) {
productThreads[i].start();
}
for (int i = 0; i < consumerNum; i++) {
consumerThreads[i].start();
}
} else if (event.getSource() == stopButton) {
stopFlag = true;
// 停止生产者线程和消费者线程
for (int i = 0; i < productNum; i++) {
productThreads[i].interrupt();
}
for (int i = 0; i < consumerNum; i++) {
consumerThreads[i].interrupt();
}
}
}
public static void main(String[] args) {
MultiThreadConsumerSystem frame = new MultiThreadConsumerSystem();
frame.setVisible(true);
}
}
class Buffer {
private int[] buffer;
private int front, rear, count;
private JTextArea messageArea;
public Buffer(int bufferSize, JTextArea messageArea) {
buffer = new int[bufferSize];
front = rear = count = 0;
this.messageArea = messageArea;
}
public synchronized void put(int value, int producerID) throws InterruptedException {
while (count == buffer.length) {
messageArea.append("缓冲区已满,生产者" + producerID + "等待\n");
wait();
}
buffer[rear] = value;
rear = (rear + 1) % buffer.length;
count++;
messageArea.append("生产者" + producerID + "生产" + value + ",当前缓冲区大小为" + count + "\n");
notifyAll();
}
public synchronized int take(int consumerID) throws InterruptedException {
while (count == 0) {
messageArea.append("缓冲区已空,消费者" + consumerID + "等待\n");
wait();
}
int value = buffer[front];
front = (front + 1) % buffer.length;
count--;
messageArea.append("消费者" + consumerID + "消费" + value + ",当前缓冲区大小为" + count + "\n");
notifyAll();
return value;
}
}
class ProductThread extends Thread {
private int id;
private Buffer buffer;
private JTextArea messageArea;
public ProductThread(int id, Buffer buffer, JTextArea messageArea) {
this.id = id;
this.buffer = buffer;
this.messageArea = messageArea;
}
public void run() {
try {
while (!Thread.interrupted()) {
int value = (int) (Math.random() * 100);
buffer.put(value, id);
Thread.sleep((int) (Math.random() * 3000));
}
} catch (InterruptedException e) {
messageArea.append("生产者" + id + "已停止\n");
}
}
}
class ConsumerThread extends Thread {
private int id;
private Buffer buffer;
private JTextArea messageArea;
public ConsumerThread(int id, Buffer buffer, JTextArea messageArea) {
this.id = id;
this.buffer = buffer;
this.messageArea = messageArea;
}
public void run() {
try {
while (!Thread.interrupted()) {
int value = buffer.take(id);
Thread.sleep((int) (Math.random() * 3000));
}
} catch (InterruptedException e) {
messageArea.append("消费者" + id + "已停止\n");
}
}
}
```
这个程序实现了一个简单的生产者-消费者模型,包括一个图形界面和多个生产者线程和消费者线程。其中,`Buffer` 类表示缓冲区,`ProductThread` 类表示生产者线程,`ConsumerThread` 类表示消费者线程。在 `MultiThreadConsumerSystem` 类中,`initGUI` 方法初始化了窗口界面,`actionPerformed` 方法响应开始和停止按钮的事件,并创建和启动生产者线程和消费者线程。
在 `Buffer` 类中,`put` 方法表示生产者放置产品到缓冲区的操作,如果缓冲区已满,则等待;`take` 方法表示消费者从缓冲区取走产品的操作,如果缓冲区已空,则等待。在生产者和消费者线程中,调用 `put` 方法和 `take` 方法即可实现生产和消费操作。如果线程被中断,则表示该线程已停止。
注意,该程序仅作为一个简单的示例,实际应用中还需要考虑更多的细节和异常处理。
阅读全文