SwingUtilities.invokeLater
是否提供同步?
的例子:
public class Threads {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
new Threads().test();
}
}).start();
}
List<Integer> list = new ArrayList<>();
void test() {
System.out.println(Thread.currentThread().toString());
for (int i=0; i<10000000; i++) {
list.add(i);
}
SwingUtilities.invokeLater(() -> {
System.out.println(Thread.currentThread().toString());
list.forEach(System.out::println); // list auto synchronized?
});
}
}
当我在AWT线程中从列表中读取值时,
会是list
同步吗?
swinguutilities。invokeLater提供同步?
。它只是稍后运行它的参数。
当我在AWT线程中从列表中读取值时,列表会同步吗?
不,但不需要。它被创建并赋值后被发送给invokeLater
。它不会在任何以后的时间改变,所以它不会改变,而代码发送到invokeLater
被执行。
总结一些事实:
- 通常Swing不是线程安全的
- 所有与gui相关的内容都在awt事件调度线程上运行
- EDT不保证执行顺序
- EDT将耗时的工作分派给工作线程(>工作模式)
- EDT应该只执行与gui相关的小任务,否则UI将冻结
SwingUtilities.invokeLater
基于awt.EventQueue.invokeLater
因此,如果您有SwingUtilities.invokeLater
并给它一个Runnable(您的函数),这个Runnable将被放入调度线程(EDT)的事件队列中,该线程将异步执行您的Runnable。
确切地说:
是的,作为invokeLater
的一部分,您的代码将在EDT上并行运行(如果这是您的意思),EDT与主线程异步运行。
不,当"另一个线程进入它"时,它不同步。因为它被指定只由EDT执行。
虽然这不是问题的一部分:EDT不应该被这样滥用。相反,您应该将此任务放入工作线程中,并让EDT做它创建的工作:将GUI相关的任务分派给工作线程。