Java 调用器的使用
我很确定所有这些方法都会奏效,但我希望大家能就哪种方法最好发表意见 考虑一下(不幸的)情况,在这种情况下,用户界面变化代码和合理密集(平均500毫秒)的逻辑代码混合在一起,而且不可分割。所有正在更改的ui组件都位于一个面板上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
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();
您会选择以下三种方法中的哪一种?为什么
因此,选项2(建议修改)应该是它。在编写多线程代码时,慢而正确总是比快而随机的错误要好。首先,我会让它运行单线程。作为其中不可或缺的一部分,我会确保我有好的代码(例如,不扩展
线程
和JPanel
),并将“业务”逻辑与UI、测试等很好地分离。这可能不是什么了不起的事情,但它是可交付的。将其检查到版本控制中。然后也许看看是否有一个小的,热的部分,我可以做平行
有一些极端的方法可以解决多线程问题。在没有共享状态的情况下,我们可以将不可变的操作事件从UI排队,并将不可变的更新事件重新排队以替换模型的UI副本。或者,我们可以共享状态并非常小心地锁定(我建议使用可能工作的最大锁-小心回调)
可能需要注意的是,您不必为每一件小事都添加侦听器。您可以使用粗粒度侦听器,然后快速扫描数据结构以获取更新
需要注意的一点是,UI发送到“业务”模型的操作和反向状态更新应该尽可能地解耦(即从SwingWorker运行)。首先,我会让它运行单线程。作为其中不可或缺的一部分,我会确保我有好的代码(例如,不扩展
线程
和JPanel
),并将“业务”逻辑与UI、测试等很好地分离。这可能不是什么了不起的事情,但它是可交付的。将其检查到版本控制中。然后也许看看是否有一个小的,热的部分,我可以做平行
有一些极端的方法可以解决多线程问题。在没有共享状态的情况下,我们可以将不可变的操作事件从UI排队,并将不可变的更新事件重新排队以替换模型的UI副本。或者,我们可以共享状态并非常小心地锁定(我建议使用可能工作的最大锁-小心回调)
可能需要注意的是,您不必为每一件小事都添加侦听器。您可以使用粗粒度侦听器,然后快速扫描数据结构以获取更新
需要注意的一点是,UI发送到“业务”模型的操作和反向状态更新应该尽可能地解耦(即从
SwingWorker
运行)。重新验证和重新绘制是线程安全的。它们内置了自己的调用器,您可以随时从任何线程调用重新验证和重新绘制。它甚至非常智能,如果在实际验证任何内容之前调用revalidate一千次,它会将所有这一千次调用合并到一个调用中。重新验证和重新绘制是线程安全的。它们内置了自己的调用器,您可以随时从任何线程调用重新验证和重新绘制。甚至