Java程序执行问题

时间:2013-10-14 02:31:01

标签: java multithreading jwindow

我有一个关于我一直在努力的事情的一般性问题,并且现在正在寻找答案3天(并且基本上已经放弃了纯粹的挫折感。)

场景1;

A)调用方法,创建并显示“Please wait ..”JWindow组件,其中包含.setVisible(true)

B)调用方法进行简单计算,System.out进行结果

C)“请等待..”在步骤B执行期间按预期持续

D)步骤B终止并且在“请稍候”窗口中调用.setVisible(false)并按预期方式进行

到目前为止,非常好。

情景2;

与方案1相同,不同之处在于步骤B中的工作要复杂得多,并且调用一个自定义类,该类执行大量的db查询/写入,平均需要大约3-6秒才能完成。自定义类不可运行或线程化,只需使用;

调用
customClass cc = new customClass();
cc.makeMyDataPlease();
  • 无论出于何种原因,在方案2中,.setVisible(true)步骤'A'在之后复杂的工作步骤'B'完成后才会发生。

我现在花了2 1/2天的时间试验了这个网站上发现的这些类型问题的许多解决方案,其他人没有运气。尝试过swingworker,invokelater,thread等,并得出结论,我需要在撕掉更多头发之前对此进行更多调查。

我遇到了类似的问题,该方法连接到网址并发布数据。我试图在Web连接例程启动之前在简单的JLabel上设置文本,但它也失败了。文本是在Web例程完成后设置的。

就好像VM正在线程化每个语句执行。

我怀疑mysql类和网络URL类共享属性(网络?),冻结其他可能没有时间完成的任务。

以下是我的问题/疑惑:

如果主java线程中的执行是顺序的,除非创建/调用新线程,为什么会干扰该setVisible(true)语句?它在逻辑上必须在执行数据库例程语句之前完成,但它没有。

java确保一个语句在下一个语句之前完全执行的最终方式是什么? (或者至少,下一个开始,因为我确信VM可以足够快地执行setVisible,甚至可以同步启动)。

提前致谢

具体来说我的问题是;处理java中“阻止程序”例程所涉及的并发问题以及如何最好地在这些范围内工作时,最佳做法是什么。

1 个答案:

答案 0 :(得分:2)

  

与方案1相同,但步骤B中的工作要复杂得多   并调用一个自定义类,它执行一堆数据库查询/写入   平均需要3-6秒才能完成。自定义类是   不可运行或线程,只需调用;

     

customClass cc = new customClass(); cc.makeMyDataPlease();对于   无论出于何种原因,在场景2中,.setVisible(true)步骤'A'都可以   直到复杂的工作步骤'B'完成后才会发生。

问题是,Swing是一个单线程环境。期望与UI的所有交互在事件调度线程的上下文中执行。阻止此线程的任何进程都将阻止它处理新事件,包括绘制请求。

正在发生的情况是,场景2最有可能阻止EDT,阻止它显示窗口,而是在所有处理完成时,EDT在打开事件后立即响应关闭事件。 / p>

由于框架的结构方式,您必须确保;

  1. 对UI的所有交互和修改都在EDT中完成。
  2. 任何长时间运行或阻止过程都在EDT之外完成。
  3. 首先查看Concurrency in Swing了解更多详情。

    没有进一步的证据,我的直觉是使用SwingWorker

    例如......

    import java.awt.EventQueue;
    import java.util.concurrent.ExecutionException;
    import javax.swing.JLabel;
    import javax.swing.JWindow;
    import javax.swing.SwingWorker;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class QuickWorker {
    
        public static void main(String[] args) {
            new QuickWorker();
        }
    
        public QuickWorker() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JWindow window = new JWindow();
                    window.add(new JLabel("Look no hands!"));
                    window.pack();
                    window.setLocationRelativeTo(null);
    
                }
            });
        }
    
        public class Worker extends SwingWorker<Object, Object> {
    
            private JWindow window;
    
            public Worker(JWindow window) {
                this.window = window;
            }
    
            @Override
            protected Object doInBackground() throws Exception {
                // Long running process...
                Thread.sleep(5000);
                return "All done";
            }
    
            @Override
            protected void done() {
                try {
                    // Get the results of the process if you want them...
                    get();
                } catch (InterruptedException | ExecutionException ex) {
                    ex.printStackTrace();
                }
                window.dispose();
                // This is only here because the example will keep running without it :P
                System.exit(0);
            }
        }
    }