Java Swing 实现生产者-消费者问题:多线程同步与互斥
使用 Java Swing 实现生产者-消费者问题:多线程同步与互斥
本文将使用 Java Swing 库,通过多线程同步和互斥技术,编写生产者-消费者问题示例程序,并提供图形化界面展示生产和消费过程。
代码示例
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ProducerConsumer extends JFrame implements ActionListener {
private final Object lock = new Object();
private JLabel label;
private JButton startButton, stopButton;
private JTextArea producerTextArea, consumerTextArea;
private Thread producerThread, consumerThread;
private boolean running = false;
private int buffer = 0;
public ProducerConsumer() {
setTitle('Producer-Consumer Problem');
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout());
label = new JLabel('Buffer: ' + buffer);
panel1.add(label);
JPanel panel2 = new JPanel();
panel2.setLayout(new GridLayout(1, 2));
producerTextArea = new JTextArea(10, 20);
producerTextArea.setEditable(false);
JScrollPane producerScrollPane = new JScrollPane(producerTextArea);
panel2.add(producerScrollPane);
consumerTextArea = new JTextArea(10, 20);
consumerTextArea.setEditable(false);
JScrollPane consumerScrollPane = new JScrollPane(consumerTextArea);
panel2.add(consumerScrollPane);
JPanel panel3 = new JPanel();
panel3.setLayout(new FlowLayout());
startButton = new JButton('Start');
startButton.addActionListener(this);
panel3.add(startButton);
stopButton = new JButton('Stop');
stopButton.addActionListener(this);
stopButton.setEnabled(false);
panel3.add(stopButton);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(panel1, BorderLayout.NORTH);
contentPane.add(panel2, BorderLayout.CENTER);
contentPane.add(panel3, BorderLayout.SOUTH);
}
public static void main(String[] args) {
ProducerConsumer frame = new ProducerConsumer();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
running = true;
startButton.setEnabled(false);
stopButton.setEnabled(true);
producerThread = new Thread(new ProducerRunnable());
consumerThread = new Thread(new ConsumerRunnable());
producerThread.start();
consumerThread.start();
} else if (e.getSource() == stopButton) {
running = false;
startButton.setEnabled(true);
stopButton.setEnabled(false);
producerThread.interrupt();
consumerThread.interrupt();
}
}
private class ProducerRunnable implements Runnable {
public void run() {
while (running) {
synchronized (lock) {
while (buffer >= 10) {
try {
lock.wait();
} catch (InterruptedException e) {
return;
}
}
buffer++;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText('Buffer: ' + buffer);
producerTextArea.append('Produced 1 item\n');
}
});
lock.notifyAll();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}
private class ConsumerRunnable implements Runnable {
public void run() {
while (running) {
synchronized (lock) {
while (buffer <= 0) {
try {
lock.wait();
} catch (InterruptedException e) {
return;
}
}
buffer--;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText('Buffer: ' + buffer);
consumerTextArea.append('Consumed 1 item\n');
}
});
lock.notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
return;
}
}
}
}
}
代码说明
- GUI 界面: 使用 Java Swing 库创建图形界面,包含显示缓冲区状态的标签、展示生产者和消费者操作日志的文本区域,以及控制程序运行的“Start”和“Stop”按钮。
- 生产者和消费者线程: 分别创建
ProducerRunnable和ConsumerRunnable类,实现生产者和消费者的线程逻辑。 - 同步与互斥: 使用
synchronized关键字和lock对象保证对共享变量buffer的访问是同步的。生产者和消费者线程使用wait()和notifyAll()方法进行协调。 - 界面更新: 使用
SwingUtilities.invokeLater()方法将界面更新操作放在事件调度线程中,确保界面操作在安全线程中执行。 - 延迟模拟: 使用
Thread.sleep()方法模拟生产和消费过程中的延迟。 - 按钮事件处理: 使用
actionPerformed()方法处理“Start”和“Stop”按钮的单击事件,控制线程的启动和停止。
运行结果
运行程序后,会显示一个包含标签、文本区域和按钮的窗口。单击“Start”按钮开始模拟生产者-消费者问题,界面将实时显示缓冲区状态和生产/消费日志。单击“Stop”按钮停止模拟。
总结
本文通过一个简单的示例程序,展示了如何使用 Java Swing 库和多线程技术实现生产者-消费者问题,并提供图形化界面进行展示。希望本文能帮助读者了解多线程同步和互斥的概念,以及如何在实际应用中使用它们解决并发访问问题。
注意: 本文仅提供一个简单的示例程序,实际应用中可能需要更复杂的逻辑和功能。请根据实际需求进行调整和扩展。
原文地址: https://www.cveoy.top/t/topic/nG3V 著作权归作者所有。请勿转载和采集!