当前位置: 首页 > 知识库问答 >
问题:

AWT调度线程执行可运行时Java通知

罗宪
2023-03-14

所以基本上我将为我的应用程序更新GUI,所以我使用静态方法

void javax.swing.SwingUtilities。invokeLater(可运行doRun)

但我想把我的初始化代码放在可运行的地方,把逻辑代码放在外面。但是,如果我调用invokeLater方法,我的主线程和AWT线程将处于争用状态,因为我的主进程将在调用 方法之后尝试调用我的逻辑代码,但由于JFrame(在我的例子中)尚未初始化,所以我的主程线很可能会赢得争用,从而引发异常。

我想我可以等待事件调度线程执行runnable,然后在它初始化初始化代码时从runnable发出通知。但是不知道什么原因,下面的代码(缩写)不行。

对于轻量级应用程序,runnable可能会赢得竞争条件,因此不会产生任何异常,但是在我的应用程序中,初始化代码更长。

断续器:

public class SSCCE {
    private static JFrame frame;
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                synchronized (this) {
                    frame = new JFrame();
                    frame.setTitle("JFrame");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLocationRelativeTo(null);
                    this.notifyAll();
                    System.out.println("Notified all");
                }
            }
        };
        synchronized (r) {
            try {
                System.out.println("Waiting"); // EDIT this line was after the wait method, and therefore it didn't execute.
                r.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException("Unexpected disruption whilst waiting for the \"Event-Dispatching thread\".",e);
            }
        }
        SwingUtilities.invokeLater(r);
        frame.setVisible(true);
        frame.getContentPane().add(new JLabel("Hello World!"));
        frame.pack();
    }
}

提前谢谢!

共有1个答案

佟嘉祯
2023-03-14

您的错误很简单:您在尝试等待结果后调用了(如果它有效的话,您就是)invokeLater

synchronized (r) {
  try {
    …
    r.wait(); // <- here you are waiting
  } catch (InterruptedException e) {
    …
  }
}
SwingUtilities.invokeLater(r); // <- never reached, you are waiting above

因此,显而易见的解决方法是先调用SwingUtilities.invokeLater(r);,然后调用etc

但那已经相当过时了,有方法< code > swing utilities . invokeendwait(r);在EDT中调度< code>Runnable并等待其完成。所以你不需要自己编程你的同步和通知。

但请注意,在 invokeLater 之后的主方法中的行正在操作 UI,因此应该像 JFrame 的构造一样放置在 EDT 中,否则您仍然违反了 Swing 的线程策略,并且仍然可能获得争用条件。

您的main线程可以同时执行EDT的事情,如果您愿意,它可以等待UI构造。但是它不应该操作UI本身。这种操作也与您希望将“逻辑代码外部”的声明相矛盾,因为操作JFrame不属于“逻辑代码”。

 类似资料:
  • 问题内容: 根据我一直在阅读的定义: 线程基本上是并发(同时)运行的代码段 。 但是,如何在存在线程调度程序的情况下同时运行它们? 我读到,线程调度程序基本上是从线程池中随机选择一个线程在某个时刻运行。从中我得到一个确切的时间点,只有一个可运行线程真正处于运行状态(运行)。( 所有这些均来自SCJP Sun认证程序员学习指南 )有人可以澄清吗? 这些线程是否真正同时运行? 问题答案: 但是,如何在

  • 调度并执行内核线程 initproc 在uCore执行完proc_init函数后,就创建好了两个内核线程:idleproc和initproc,这时uCore当前的执行现场就是idleproc,等到执行到init函数的最后一个函数cpu_idle之前,uCore的所有初始化工作就结束了,idleproc将通过执行cpu_idle函数让出CPU,给其它内核线程执行,具体过程如下: void cpu_i

  • 我需要帮助设计基于多线程的应用程序,包括动态url创建和线程处理。 我在我的应用程序中使用了一个Spring调度器,它每30秒调度一次。从这个调度方法中,我调用了一些基于服务的api,它在循环中,而且我需要每个API有一个线程池执行器,上面有一个线程处理。 由于这个过程是从计划方法开始的,所以每次创建新的线程池时,这就是问题所在。你可以在代码中看到。 我想要的是,如果对于任何一个应用编程接口,如果

  • 问题内容: 我在使用netbeans Swing GUI的线程方面遇到问题。这是我第一次真正尝试使用Java的文件系统通知程序为备份程序开发GUI。我有两个文件和。 我几乎要发生的事情是,在文本字段中输入目录路径,该目录路径将创建一个同步线程,该线程将创建一个新的同步对象,然后对该对象进行调用。当该目录中的文件更改时,我想将有关更改的文本添加到列表中。 在当前状态下,UI不再无响应,但是并没有在我

  • 我正在尝试将我制作的两个简单程序合并为一个。罐子我两个都打包了。将jar装入新的jar并在运行时使用。getRuntime()。exec方法来执行它们。 代码: 问题是只执行proj1.jar,proj2.jar不运行。我是新来的java,不知道为什么会这样。我该怎么解决这个问题?我想要两个文件都被执行。

  • 我尝试在每次创建活动时运行以下线程。它第一次工作,但如果我按下后退按钮并尝试再次导航到活动,它总是崩溃第二次。我怎样才能确保这个线程每次都运行成功呢?