Java 调用器的使用

Java 调用器的使用,java,swing,Java,Swing,我很确定所有这些方法都会奏效,但我希望大家能就哪种方法最好发表意见 考虑一下(不幸的)情况,在这种情况下,用户界面变化代码和合理密集(平均500毫秒)的逻辑代码混合在一起,而且不可分割。所有正在更改的ui组件都位于一个面板上 01 new Thread(){ 02 public void run(){ 03 04 for (int i = 0; i < 100; i++){ 05 // some processing 06 doSomething(); 07

我很确定所有这些方法都会奏效,但我希望大家能就哪种方法最好发表意见

考虑一下(不幸的)情况,在这种情况下,用户界面变化代码和合理密集(平均500毫秒)的逻辑代码混合在一起,而且不可分割。所有正在更改的ui组件都位于一个面板上

01 new Thread(){
02  public void run(){
03 
04  for (int i = 0; i < 100; i++){
05      // some processing
06      doSomething();
07      // update some ui components
08      panel.doSomeUi();
09  }
10 
11  panel.revalidate();
12  panel.repaint();
13 
14 }}.start();
01新线程(){
02公开作废运行(){
03
04表示(int i=0;i<100;i++){
05//一些处理
06 doSomething();
07//更新一些ui组件
08 panel.doSomeUi();
09  }
10
11.重新验证();
12.面板重新喷漆();
13
14}}.start();
您会选择以下三种方法中的哪一种?为什么

  • 在invokeLater中包装所有代码
  • 在doSomeUi()内调用invokeLater,然后再次调用以重新验证/重新绘制
  • 仅在结束时使用invokeLater进行重新验证/重新绘制
  • 我的:

    选项1将在所有处理发生时挂起事件处理线程(EPT)

    选项2在创建许多新的可运行文件时会考虑开销问题,在特殊情况下,如果组件需要一些后续的ui更改才有效,则可能会导致ui以半完整状态更新

    选项3是最有效的,但可能存在一些线程安全问题

    你喜欢阅读和考虑使用工人线程吗?同时检查

    课程明确指出:

    事件分派线程上的任务 必须尽快完成;如果他们没有, 未处理的事件备份和用户 接口变得无响应

    当Swing程序需要执行时 一个长期运行的任务,它通常使用 工作线程之一

    你读过并考虑使用工作者线程吗?同时检查

    课程明确指出:

    事件分派线程上的任务 必须尽快完成;如果他们没有, 未处理的事件备份和用户 接口变得无响应

    当Swing程序需要执行时 一个长期运行的任务,它通常使用 工作线程之一

    doSomeUi()应该封装在invokeLater()中,应该触发任何必要的重绘/重绘操作——Swing UI线程将在您继续计算时进行绘制

    在现代虚拟机上,创建大量短期可运行程序的开销很小,不应该成为问题

    因此,选项2(建议修改)应该是它。在编写多线程代码时,慢而正确总是比快而随机的错误要好。

    doSomeUi()部分应该封装在调用器中()应该触发任何必要的重新绘制/重画——Swing UI线程将在您继续计算时进行绘制

    在现代虚拟机上,创建大量短期可运行程序的开销很小,不应该成为问题


    因此,选项2(建议修改)应该是它。在编写多线程代码时,慢而正确总是比快而随机的错误要好。

    首先,我会让它运行单线程。作为其中不可或缺的一部分,我会确保我有好的代码(例如,不扩展
    线程
    JPanel
    ),并将“业务”逻辑与UI、测试等很好地分离。这可能不是什么了不起的事情,但它是可交付的。将其检查到版本控制中。然后也许看看是否有一个小的,热的部分,我可以做平行

    有一些极端的方法可以解决多线程问题。在没有共享状态的情况下,我们可以将不可变的操作事件从UI排队,并将不可变的更新事件重新排队以替换模型的UI副本。或者,我们可以共享状态并非常小心地锁定(我建议使用可能工作的最大锁-小心回调)

    可能需要注意的是,您不必为每一件小事都添加侦听器。您可以使用粗粒度侦听器,然后快速扫描数据结构以获取更新


    需要注意的一点是,UI发送到“业务”模型的操作和反向状态更新应该尽可能地解耦(即从SwingWorker运行)。

    首先,我会让它运行单线程。作为其中不可或缺的一部分,我会确保我有好的代码(例如,不扩展
    线程
    JPanel
    ),并将“业务”逻辑与UI、测试等很好地分离。这可能不是什么了不起的事情,但它是可交付的。将其检查到版本控制中。然后也许看看是否有一个小的,热的部分,我可以做平行

    有一些极端的方法可以解决多线程问题。在没有共享状态的情况下,我们可以将不可变的操作事件从UI排队,并将不可变的更新事件重新排队以替换模型的UI副本。或者,我们可以共享状态并非常小心地锁定(我建议使用可能工作的最大锁-小心回调)

    可能需要注意的是,您不必为每一件小事都添加侦听器。您可以使用粗粒度侦听器,然后快速扫描数据结构以获取更新


    需要注意的一点是,UI发送到“业务”模型的操作和反向状态更新应该尽可能地解耦(即从
    SwingWorker
    运行)。

    重新验证和重新绘制是线程安全的。它们内置了自己的调用器,您可以随时从任何线程调用重新验证和重新绘制。它甚至非常智能,如果在实际验证任何内容之前调用revalidate一千次,它会将所有这一千次调用合并到一个调用中。

    重新验证和重新绘制是线程安全的。它们内置了自己的调用器,您可以随时从任何线程调用重新验证和重新绘制。甚至