如果我从其他线程引用对象到AWT线程,我需要同步吗?



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相关的任务分派给工作线程。

最新更新