나는 이것에 대해 약간의 연구를 해왔지만 여전히 가장 적게 말하는 것은 매우 혼란 스럽습니다.
누구든지 언제 사용 Task
하고 언제 사용 Platform.runLater(Runnable);
하는지에 대한 구체적인 예를 줄 수 있습니까 ? 차이점은 정확히 무엇입니까? 이들 중 언제 사용 하는가에 대한 황금률이 있습니까?
또한 내가 틀렸지 만이 두 “객체”가 GUI의 주 스레드 내부에 다른 스레드를 만드는 방법이 아닌 경우에도 수정하십시오 (GUI 업데이트에 사용됨)?
답변
사용하여 Platform.runLater(...)
빠르고 간단하게 작업하고 Task
복잡하고 큰 작업.
예 : Platform.runLater(...)
긴 계산에 사용할 수없는 이유 (아래 참조에서 발췌).
문제 : 0에서 1 백만까지 계산되는 백그라운드 스레드와 UI의 업데이트 진행률 표시 줄.
다음을 사용하는 코드 Platform.runLater(...)
:
final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
@Override public void run() {
for (int i = 1; i <= 1000000; i++) {
final int counter = i;
Platform.runLater(new Runnable() {
@Override public void run() {
bar.setProgress(counter / 1000000.0);
}
});
}
}).start();
이것은 끔찍한 코드 덩어리이며, 자연에 반하는 범죄입니다 (일반적으로 프로그래밍). 첫째,이 Runnables의 이중 중첩을 보는 것만으로도 뇌 세포를 잃게됩니다. 둘째, 작은 Runnables로 이벤트 대기열을 휩쓸 것입니다. 실제로는 백만 개입니다. 분명히, 우리는 UI와 다시 통신하는 백그라운드 워커를 더 쉽게 작성하기 위해 약간의 API가 필요했습니다.
Task를 사용하는 코드 :
Task task = new Task<Void>() {
@Override public Void call() {
static final int max = 1000000;
for (int i = 1; i <= max; i++) {
updateProgress(i, max);
}
return null;
}
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
이전 코드에 나타난 결함이 없습니다.
참조 :
JavaFX 2.0의 작업자 스레딩
답변
Platform.runLater
: GUI가 아닌 스레드에서 GUI 구성 요소를 업데이트해야하는 경우이를 사용하여 업데이트를 대기열에 넣을 수 있으며 가능한 한 빨리 GUI 스레드에서 처리합니다.Task
Worker
GUI 스레드 외부에서 긴 작업을 실행해야하지만 (애플리케이션 동결을 방지하기 위해) 일부 단계에서 여전히 GUI와 상호 작용해야 할 때 사용되는 인터페이스를 구현합니다 .
Swing에 대해 잘 알고 있다면 전자는 SwingUtilities.invokeLater
의 개념과 같고 후자는의 개념과 같습니다 SwingWorker
.
Task 의 javadoc은 사용 방법을 명확히해야하는 많은 예제를 제공합니다. 동시성 에 대한 자습서를 참조 할 수도 있습니다 .
답변
이제 람다 버전으로 변경할 수 있습니다.
@Override
public void actionPerformed(ActionEvent e) {
Platform.runLater(() -> {
try {
//an event with a button maybe
System.out.println("button is clicked");
} catch (IOException | COSVisitorException ex) {
Exceptions.printStackTrace(ex);
}
});
}
답변
명시 적 Platform.runLater ()를 사용하는 한 가지 이유는 UI의 속성을 서비스 (결과) 속성에 바인딩했기 때문일 수 있습니다. 따라서 바인딩 된 서비스 속성을 업데이트하는 경우 runLater ()를 통해이를 수행해야합니다.
JavaFX 애플리케이션 스레드라고도하는 UI 스레드에서 :
...
listView.itemsProperty().bind(myListService.resultProperty());
...
서비스 구현 (백그라운드 작업자) :
...
Platform.runLater(() -> result.add("Element " + finalI));
...
답변
