JavaFX实现生产者-消费者问题:同步和互斥技术
本文使用JavaFX作为界面的实现方式,展示了如何使用Java语言在Windows操作系统下,采用进程(线程)同步和互斥的技术编写程序实现生产者-消费者问题。
生产者-消费者问题是经典的多线程编程问题,其中有两个角色:生产者和消费者。生产者负责生产数据,并将其放入共享缓冲区中;消费者则负责从共享缓冲区中取出数据,并进行处理。由于共享缓冲区的存在,需要对其进行同步和互斥操作,以避免生产者和消费者同时访问导致数据错误的发生。
下面给出基于JavaFX的生产者-消费者问题的代码实现:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ProducerConsumer extends Application {
private TextArea bufferArea;
private TextField produceField;
private TextField consumeField;
private Button produceButton;
private Button consumeButton;
private Buffer buffer = new Buffer();
@Override
public void start(Stage primaryStage) throws Exception {
// 创建UI界面
bufferArea = new TextArea();
bufferArea.setEditable(false);
bufferArea.setWrapText(true);
produceField = new TextField();
produceButton = new Button('Produce');
produceButton.setOnAction(e -> {
try {
int data = Integer.parseInt(produceField.getText());
buffer.produce(data);
produceField.clear();
} catch (NumberFormatException ex) {
showAlert('Invalid input');
}
});
consumeField = new TextField();
consumeButton = new Button('Consume');
consumeButton.setOnAction(e -> {
try {
int data = buffer.consume();
consumeField.setText(String.valueOf(data));
} catch (InterruptedException ex) {
showAlert('Interrupted');
}
});
GridPane inputPane = new GridPane();
inputPane.setHgap(10);
inputPane.setVgap(10);
inputPane.addRow(0, new Label('Produce:'), produceField, produceButton);
inputPane.addRow(1, new Label('Consume:'), consumeField, consumeButton);
VBox root = new VBox(10);
root.getChildren().addAll(bufferArea, inputPane);
// 创建生产者和消费者线程
Thread producerThread = new Thread(() -> {
try {
while (true) {
int data = (int) (Math.random() * 100);
buffer.produce(data);
Platform.runLater(() -> {
bufferArea.appendText('Produced ' + data + '\n');
});
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumerThread = new Thread(() -> {
try {
while (true) {
int data = buffer.consume();
Platform.runLater(() -> {
bufferArea.appendText('Consumed ' + data + '\n');
});
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 启动线程
producerThread.start();
consumerThread.start();
Scene scene = new Scene(root, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
private void showAlert(String message) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setContentText(message);
alert.showAndWait();
}
public static void main(String[] args) {
launch(args);
}
}
class Buffer {
private static final int MAX_SIZE = 10;
private int[] data = new int[MAX_SIZE];
private int head = 0;
private int tail = 0;
private int count = 0;
public synchronized void produce(int data) throws InterruptedException {
while (count == MAX_SIZE) {
wait();
}
this.data[tail] = data;
tail = (tail + 1) % MAX_SIZE;
count++;
notifyAll();
}
public synchronized int consume() throws InterruptedException {
while (count == 0) {
wait();
}
int data = this.data[head];
head = (head + 1) % MAX_SIZE;
count--;
notifyAll();
return data;
}
}
上述代码中,首先创建了一个UI界面,包括一个TextArea用于显示生产者和消费者的操作记录,以及两个TextField和两个Button用于输入生产者的数据和输出消费者的数据。然后创建了一个Buffer类用于实现共享缓冲区,其中包括了生产者和消费者所需的同步和互斥操作。最后创建了两个线程分别用于执行生产者和消费者的操作,并在UI界面中启动这两个线程。
在生产者和消费者的操作中,为了避免UI界面的阻塞,使用了Platform.runLater()方法将更新UI界面的操作放入JavaFX的事件队列中,以在UI线程上执行。
以上就是基于JavaFX的生产者-消费者问题的代码实现。注意,该实现并未考虑生产者和消费者线程的结束,需要根据具体情况做出相应的改进。
原文地址: https://www.cveoy.top/t/topic/nG6n 著作权归作者所有。请勿转载和采集!