美好的一天,
我尝试调整我的JavaFx技能,我正在编写一个小媒体播放器。 因此,有一个滑块对象将负责向用户显示已用时间(并在用户想要的情况下搜索曲目位置)。
为了监控当前的轨道位置,我使用另一个线程,该线程将询问每100毫秒经过的时间。它会更新DoubleProperty,其中的slidervalue将被绑定到。 这样可行,但如果我这样做,CPU使用率会增加到70-80%。
段:
Task task = new Task<Void>() {
@Override public Void call() throws InterruptedException {
double time=0;
double dummy=0;
while(true) {
try{
if(time == tmp.getPlaytime()){
dummy += 0.1;
}else{
dummy = time;
}
updateProgress(dummy, tracklength.getValue());
time = tmp.getPlaytime();
Thread.sleep(100);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
};
trackposition.bind(task.progressProperty());
new Thread(task).start();
tmp是提供经过时间的对象,该方法可以引发异常,因此是try / catch块。 tracklength是一个DoubleProperty,它以秒为单位提供轨道的长度。 由于我在tmp中的方法中只有一秒的时间分辨率,因此我使用虚拟变量来制作平滑的滑块动画。 这个线程方法的想法取自Oracle Tutorial
我知道多线程和GUI是一个难题,但您是否知道如何降低CPU使用率? (在你看来,runLater()方法会更好吗?因为runLater意味着我不知道它什么时候会被执行,我无法提供一个平滑的转换,并且不会提供#34;#34;#34;希望&#34;然后使用它)
谢谢
答案 0 :(得分:0)
我已经创建了这个简短的示例来测试您的任务,它运行完美,没有相关的CPU使用率。
private volatile boolean running = true;
@Override
public void start(Stage primaryStage) {
final Media song = new Media(<Media URL>);
MediaPlayer media_player = new MediaPlayer(song);
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws InterruptedException {
double time=0;
double dummy=0;
while(running) {
try{
if(time == media_player.getCurrentTime().toSeconds()){
dummy += 0.1;
}else{
dummy = time;
}
updateProgress(dummy, media_player.getTotalDuration().toSeconds());
time = media_player.getCurrentTime().toSeconds();
Thread.sleep(100);
}
catch(Exception e){
System.out.println(e.getMessage());
running=false;
}
}
return null;
}
};
Slider slider = new Slider(0,100,0);
slider.valueProperty().bind(task.progressProperty().multiply(100));
media_player.setOnReady(() -> {
new Thread(task).start();
media_player.play();
});
StackPane root = new StackPane();
root.getChildren().add(slider);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
尝试运行它,检查它是否有效,以及CPU的使用情况。