【发布时间】:2016-11-30 14:47:08
【问题描述】:
我正在使用无限循环从我的应用程序中播放一些动画,效果很好。我需要在用户需要时等待我的线程,并在用户需要时再次启动。为此,我通过单击我的根布局来使用等待和通知线程,首先单击使我的线程等待,然后单击使我的线程运行。这也可以按我的意愿工作。
我的问题是当我快速点击时,这意味着当我等待并立即通知时,我的应用程序会挂起。
那么我该如何解决这个问题???
下面是我的代码:
public class AboutC implements Initializable {
public VBox mainLayout;
@FXML
private
Label nameLvl = new Label();
@FXML
private
Label rollLvl = new Label();
@FXML
private
Label batchLvl = new Label();
@FXML
private
Label depLvl = new Label();
@FXML
private
Label uniLvl = new Label();
@FXML
private Circle circle = new Circle();
private int count = 0;
private boolean run = true;
private Thread thread;
private Task task;
private FadeTransition fd;
private RotateTransition rt;
private Timeline tm;
@Override
public void initialize(URL location, ResourceBundle resources) {
ArrayList<AboutDevelopers> list = new ArrayList<>();
list.add(....)
fd = new FadeTransition(Duration.seconds(4), mainLayout);
fd.setFromValue(0.2);
fd.setToValue(1.0);
fd.setCycleCount(2);
rt = new RotateTransition(Duration.seconds(4), circle);
rt.setByAngle(360);
rt.setAutoReverse(true);
rt.setCycleCount(2);
KeyFrame keyFrame = new KeyFrame(Duration.seconds(4), new KeyValue(circle.radiusProperty(), 0));
tm = new Timeline(keyFrame);
tm.setCycleCount(2);
tm.setAutoReverse(true);
task = new Task<Void>() {
@Override
synchronized public Void call() throws Exception {
int i = 0;
while (true) {
if (run) {
Platform.runLater(() -> {
nameLvl.setText(list.get(count).getName());
rollLvl.setText("Roll: " + list.get(count).getRoll());
batchLvl.setText("Batch: " + list.get(count).getBatch());
depLvl.setText("Department: " + list.get(count).getDepartment());
uniLvl.setText(list.get(count).getUniversity());
circle.setFill(new ImagePattern(new Image(list.get(count).getImagePath())));
fd.play();
rt.play();
tm.play();
count++;
if (count >= list.size())
count = 0;
});
sleep(10000);
} else
wait();
}
}
};
thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
void setStage(Stage stage) {
stage.setOnCloseRequest(event -> {
thread.interrupt();
});
}
public void playThread(){
if (run) {
run = false;
} else {
if(!run){
synchronized (task) {
task.notify();
}
}
run = true;
}
}
}
【问题讨论】:
-
我确信有些问题与您的问题更相似,但这是迄今为止我发现的最好的:stackoverflow.com/questions/34510/what-is-a-race-condition
-
参见this answer(第二个代码块)。重点:在通知之前更改您的标志,更重要的是 - 在
synchronized块内。 -
感谢您的时间,检查您的链接并从第一个链接了解问题,作为您的第二个链接答案,我也添加条件 if(!run) 等待并且我的通知已经具有相同的条件但是问题仍然存在。实际上我的应用程序并没有完全挂起,如果我不退出,它会在一段时间后工作。而且我是新程序员,所以我不明白您在同步块中的标志是什么意思。
-
加载fxml时为什么要初始化应该注入的字段?
-
我刚开始通过在线资源学习 javafx,几天前,当我没有初始化这些字段时,我得到了空指针,这就是我初始化这些值的原因。也许这不是一个好的做法,我现在向你学习。
标签: java multithreading javafx