Thread.sleep() 不工作。被跳过的操作

Posted

技术标签:

【中文标题】Thread.sleep() 不工作。被跳过的操作【英文标题】:Thread.sleep() not working. Operations being skipped 【发布时间】:2016-03-22 12:51:14 【问题描述】:

这段代码应该是搜索网页的html文件,将一些结果打印到一个窗口,休眠60秒然后再次重复搜索。这在 python 中工作得很好,但翻译成 java 给我带来了问题。当我尝试执行此代码时,它不再打印结果,而是无限期地休眠。如果没有 while 循环,事情似乎会按方面进行。

btnSearch.addActionListener(new ActionListener() 
        public void actionPerformed(ActionEvent arg0) 

            running = true;

            while (running) 

                exportField.setText("Searching...");


                try 

                    exportField.setText(crawler.fetchHtml(url););



                 catch (Exception e) 
                    exportField.setText("invalid parameters.");
                    e.printStackTrace();
                


                try 
                    Thread.sleep(60000);
                 catch (InterruptedException e) 

                    e.printStackTrace();
                


            

        
    );

更奇怪的是,如果我尝试以下简单的事情:

exportField.setText("Searching...");

try 
    Thread.sleep(1000);
 catch (InterruptedException e)               
    e.printStackTrace();


exportField.setText("Done Searching");

我希望输出是“正在搜索...”pause“完成搜索”,但事实并非如此。它只是输出“完成搜索”。

为了好玩而从事这个项目!任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

在我看来,您好像在 Event Dispatch Thread 内。如果是这种情况,您的 sleep()s 将运行良好 - 您的 exportField 上的重绘永远不会(在一段时间的情况下)或延迟(在简单睡眠的情况下)发生。

您应该考虑查看 SwingWorker 以了解这种长时间运行但会改变 UI 的调用。

一种简化的方法是启动一个线程并通过SwingUtilities.invokeLater() 更新 UI:

btnSearch.addActionListener(new ActionListener() 
        public void actionPerformed(ActionEvent arg0) 
            new Thread("Fetcher") 

                boolean running = true;

                public void run() 
                    running = true;

                    while (running) 
                        SwingUtilities.invokeLater(() -> exportField.setText("Searching..."));
                        try 
                            exportField.setText(crawler.fetchHtml(url));
                         catch (Exception e) 
                            SwingUtilities.invokeLater(() -> exportField.setText("invalid parameters."));
                            e.printStackTrace();
                        
                        try 
                            Thread.sleep(60000);
                         catch (InterruptedException e) 

                            e.printStackTrace();
                        
                    
                
            .start();              
        
    );

【讨论】:

谢谢@Jan。这似乎是朝着正确方向迈出的一步!我对线程一无所知,但这段代码和这些链接应该会有所帮助。 一旦您对答案感到满意,如果您接受它会很棒。祝你的项目好运。【参考方案2】:

据我所知,您正在 actionPerformed 方法内启动一个无限循环(假设 running 在某处未设置为 false),这将阻止事件调度线程上的所有事件。看看this tutorial 的摇摆。像@Jan 所说的长时间运行的事件应该使用 SwingWorker 或至少在单独的线程上完成

【讨论】:

感谢@dbrown93 的链接,至少可以从这个错误开始!

以上是关于Thread.sleep() 不工作。被跳过的操作的主要内容,如果未能解决你的问题,请参考以下文章

unittst用例操作

第二个 cin 被跳过或无法正常工作

为什么连续的scanf会被跳过或不执行

为什么连续的scanf会被跳过或不执行

performSegueWithIdentifier 被跳过 *SWIFT

Vue-if 条件不起作用。 if-Else 块似乎被跳过