【发布时间】:2018-03-11 16:01:48
【问题描述】:
所以我有这样的事情:
public class test {
final ProgressBar bar = new ProgressBar(0.0);
final int result;
final worker work = new worker();
// GUI Scene change happens here
new Thread(() -> {
result = work.doSomething(this.bar);
}).start();
}
public class worker{
public int doSomething(ProgressBar bar){
for(int i = 1; i <= 1000000; i++)
Platform.runLater(() -> { bar.setProgress(i/100000.0); });
return 51;
}
}
一切都很好,直到我不得不等待其他事情完成才能在可运行之后继续,所以我像这样改变它:
public class test {
final ProgressBar bar = new ProgressBar(0.0);
TextArea area = new TextArea();
int result;
final worker work = new worker();
final worker work2 = new worker2();
final CountDownLatch latch1 = new CountDownLatch(1);
// GUI Scene change happens here
new Thread(() -> {
result = work.doSomething(this.bar);
latch1.CountDown();
}).start();
latch1.await();
new Thread(() -> {
work2.doSomething(result, area);
}).start();
}
public class worker{
public int doSomething(ProgressBar bar){
for(int i = 1; i <= 1000000; i++)
Platform.runLater(() -> { bar.setProgress(i/100000.0); });
return 51;
}
}
public class worker2{
ArrayList<String> list = new ArrayList<>();
public int doSomething(int index, TextArea area){
Platform.runLater(() -> { area.append(list.get(index)); });
}
}
稍后我会这样做:
public class test {
final ProgressBar bar = new ProgressBar(0.0);
TextArea area = new TextArea();
int result;
final worker work = new worker();
final worker2 work2 = new worker2();
final worker3 work3 = new worker3();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(Map.keySet().size());
// This already has values
// it is not really a file array list in the map, but it is easier to show it this way
Map<String, ArrayList<File>> mapTypes;
// GUI Scene change happens here
new Thread(() -> {
result = work.doSomething(this.bar);
latch1.CountDown();
}).start();
latch1.await();
new Thread(() -> {
work2.doSomething(result, area);
}).start();
// Even thought I don't use it here I need a for each on the keyset
mapTypes.keySet().forEach((String s) -> {
new Thread(() -> {
// Here I actually load classes with a reflection
work3.doSomething(mapTypes.get(s), area);
latch2.CountDown();
}).start();
}
latch2.await();
System.out.println("Done");
}
public class worker{
public int doSomething(ProgressBar bar){
for(int i = 1; i <= 1000000; i++)
Platform.runLater(() -> { bar.setProgress(i/100000.0); });
return 51;
}
}
public class worker2{
ArrayList<String> list = new ArrayList<>();
public int doSomething(int index, TextArea area){
Platform.runLater(() -> { area.append(list.get(index)); });
}
}
public class worker3{
public int doSomething(Arraylist<File> files, TextArea area){
for (File f : files)
Platform.runLater(() -> { area.append(f.getName()); });
}
}
现在我的 gui 在切换场景时开始滞后 - 意思是 - 整个线程 1 自行处理,然后 gui 加载了所有内容。经过一番研究,我认为这是因为主线程正在处理 runLater “请求”,并且由于 await() 主线程必须等到第一个辅助线程到达 倒计时().
我的问题是,我如何管理主线程在第一个后台线程完成之前没有启动第二个后台线程?额外的问题:更新我的 GUI 而不是 Plattform.runlater() 的更有效方法是什么?
注意:
我还查看了this Question,但它并没有完全解决我的问题,因为我不需要对线程进行排队。我更需要知道如何让主线程等到子线程完成然后才继续。但是,主线程不能完全处于非活动状态,而是管理传入的更新请求。
提前谢谢你
使用的技术: - NetBeans
- JavaFX(无 FXML - 代码中设计的所有内容)
- CSS
- Java(显然)
- Windows 10 专业版
【问题讨论】:
标签: java multithreading javafx