Java GUI,需要暂停一个方法而不会冻结GUI

3

我知道这个问题是由于在主线程上调用sleep或wait引起的,解决方法是将该方法放入一个单独的线程中,然后使该线程休眠。但代码很混乱,我没有时间整理并将其拆分为单独的线程,想知道是否有其他方法可以解决这个问题?即使它不是与GUI一起工作的最干净或最常见的做法。我只需要该方法暂停约一秒钟。

5个回答

8

如果不创建单独的线程,你就无法完成这项任务。在Java中创建线程非常简单,唯一需要注意的是只能通过主线程来操作UI。因此,你需要使用类似于SwingUtilities.invokeLater()的方法。


或者,如果他需要另一种方式,他可以使用javax.swing.SwingWorker将方法移出事件分派线程(EDT)。 - ILMTitan
链接已损坏。 - Eric Reed

1

在事件线程上休眠而不导致GUI冻结是不可能的。然而,在Swing中,事件线程是在幕后创建和管理的 - 您的主线程(即源自main()方法的线程)不是事件线程。

因此,您可以安全地在主线程上休眠。


0
我为Java编写了一个超级简单的延迟函数,它不会让你的GUI冻结。每次我使用它时都能正常工作,我想它对你也会有用。
     void Delay(Long ms){

       Long dietime = System.currentTimeMillis()+ms;
       while(System.currentTimeMillis()<dietime){
           //do nothing
       }
   }

例如:要延迟线程5毫秒,请使用Delay(5L)。

这难道不会引起性能瓶颈吗?我的意思是性能损失可能导致 GUI 看起来像是冻结了。我想我在其他语言中测试过这种方法并不是很好。虽然我不确定,但如果有效的话,这是一个相当不错的解决方案,我现在要进行测试。 - Milad.Nozari
我不知道,在安卓平台上测试过,但它不起作用。也许它在JVM上能够工作。 - Milad.Nozari
这段代码与 Thread.sleep 没有区别,即它将停止当前线程的执行。因此,在 GUI 线程上执行将导致 GUI 冻结。 - default locale

0

使用单独的线程来处理代码是您唯一的解决方案。如果Swing线程启动的每个操作会阻塞GUI,则必须将其委派给单独的线程。


-6

那么在哪里声明这个线程呢?请记住,任何包含线程休眠的函数引用都会导致主线程暂停。因为主线程必须等待子线程暂停。

现实情况是,线程并不像独立的线程一样工作,因为线程必须从另一个线程启动。换句话说,如果您正在创建桌面应用程序,即使您不使用其他线程,您的应用程序也是单线程应用程序。现在,如果您开始使用线程并使它们进入睡眠状态,您很快就会发现您无法在应用程序中做其他任何事情。不,其他线程甚至不会运行,因为它们正在等待第一个线程完成休眠。为什么会这样呢?因为线程是主线程的子线程,而主线程正在等待该休眠子线程醒来。您也不能设计一个没有线程的应用程序,因为Java是单主线程应用程序。您应用程序中定义的任何线程始终在主线程内运行。

除非有人能证明我错了,否则你显然永远不会暂停你的主线程,因为这会锁定你的应用程序。然而,一旦你定义了另一个线程并使用sleep()挂起它,这也会锁定你的应用程序,因为该线程是在主应用程序的子类中定义的,因此主线程也被锁定。

因此,长话短说,暂停用户定义的线程几乎与在应用程序的任何位置调用Thread.sleep()完全相同,它会暂停整个应用程序。


2
这是不正确的。在一个新线程中睡眠只会暂停现有线程,如果现有线程正在等待某些东西(例如等待锁可用),而新线程正在阻止它发生(例如在持有该锁的同时睡眠)。两者之间必须存在某种依赖关系才能使其中一个停滞,尽管有许多间接的方式可以实现这一点。 - Stuart Cook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接