我有一种我无法解释的奇怪行为。
请看一下这个最小的例子:
public class ParallelStreamProgressMonitor
{
public static void main(String[] args)
{
List<Integer> belege = IntStream.range(1, 100).boxed().collect(Collectors.toList());
final ProgressMonitor pm = new ProgressMonitor(null, "Initialmessage", "Initial Note", 0, belege.size());
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
pm.setMaximum(belege.size());
pm.setNote("Now I am working");
AtomicInteger counter = new AtomicInteger();
belege.stream().parallel().forEach(b ->
{
System.out.println(b);
pm.setProgress(counter.getAndIncrement());
try
{
//something time consuming ...
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// ignore
}
});
}
}在执行此操作时,您通常会期望出现一个ProgressMonitor并显示执行的进度。
但这才是真正的样子:

似乎每一次并行流执行都有一个额外的ProgressMonitor实例出现。
这有什么原因吗?如何才能实现只有一个对话框显示并显示进度?
发布于 2020-12-18 10:49:23
考虑一下Swing的线程策略
一般来说,Swing并不是线程安全的。除非另有文档说明,否则所有Swing组件和相关类都必须在事件调度线程上访问。
这意味着您必须研究[经]文件,以确定“除非另有文档”是否适用,但是由于没有其他线程策略,这里没有什么可引用的。
在事件调度线程中执行操作的一种方法是将其封装到Runnable中并使用invokeLater(Runnable),但是当使用它从数量未知的工作线程发送不同的进度状态时,它们可能到达错误的顺序,而且效率也很低。因为您已经有了一个AtomicInteger,所以更好的选择是使用Timer
public class ParallelStreamProgressMonitor
{
public static void main(String[] args)
{
List<Integer> belege
= IntStream.range(1, 100).boxed().collect(Collectors.toList());
final ProgressMonitor pm = new ProgressMonitor(
null, "Initialmessage", "Initial Note", 0, belege.size());
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
pm.setMaximum(belege.size());
pm.setNote("Now I am working");
AtomicInteger counter = new AtomicInteger();
Timer timer = new Timer(250, ev -> pm.setProgress(counter.get()));
timer.start();
belege.stream().parallel().forEach(b ->
{
System.out.println(b);
counter.getAndIncrement();
//simulate something time consuming ...
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1000));
});
timer.stop();
}
}发布于 2020-12-18 10:46:29
是否真的需要使用并行处理?如果不将belege.stream().parallel().forEach(b ->替换为belege.stream().forEach(b ->,它将解决您的问题。
并行执行将涉及更多的线程,因此将从不同的上下文中多次调用进度监视器。每个线程都将显示一个进度UI,最终您将拥有多个进度UI。因此,如果您没有真正的理由使用并行执行,那么就进行顺序执行。
https://stackoverflow.com/questions/65355156
复制相似问题