简体   繁体   English

在EDT中使用OSGi EventAdmin是否安全?

[英]Is it safe to use OSGi EventAdmin within EDT?

Is EventAdmin safe to use in a Swing environment? 在Swing环境中可以安全使用EventAdmin吗? I'm asking because I've got the following sequence: 我问,因为我有以下顺序:

  • Receive an ActionListener notification from a JButton 接收来自JButton的ActionListener通知
  • Create a JPanel and put it in the properties of my Event 创建一个JPanel并将其放在我的事件的属性中
  • Use EventAdmin#sendEvent(Event) to send my event synchronously 使用EventAdmin#sendEvent(Event)同步发送我的事件
  • Receive the event in my subscriber 在我的订阅者中接收活动
  • Retrieve the JPanel from the properties and, using SwingUtilities#InvokeAndWait if not in EDT, put some JComponents inside 从属性中检索JPanel,如果不在EDT中,请使用SwingUtilities#InvokeAndWait,在其中放入一些JComponent。
  • In the caller of EventAdmin#sendEvent(), the method returns, the JPanel has been filled, I can then add it to my dialog and display it. 在EventAdmin#sendEvent()的调用方中,该方法返回,JPanel已填充,然后可以将其添加到对话框中并显示它。

The purpose of this is to let any subscriber install what it needs to a JPanel that will displayed once every subscriber has been invoked. 这样做的目的是让任何订阅者将需要的东西安装到一个JPanel上,一旦每个订阅者被调用,该面板就会显示出来。

The first time I click on my button, everything goes fine as everything is executed in the EDT. 第一次单击按钮时,一切正常,因为在EDT中执行了所有操作。 The second time, my subscriber is invoked in a thread that is not the EDT. 第二次,在不是EDT的线程中调用我的订户。 I hence execute the JComponent installation in a runnable launched by invokeAndWait. 因此,我在invokeAndWait启动的可运行程序中执行JComponent安装。 This call blocks for 5022ms (5000ms being the default EventAdmin timeout duration). 该调用将阻塞5022ms(5000ms是默认的EventAdmin超时时间)。 Once unblocked, my dialog is shown. 解除阻止后,将显示我的对话框。 The following times, my subscriber is not called anymore. 在以下情况下,不再呼叫我的订户。 It must have been blacklisted by the EventAdmin. 它必须已被EventAdmin列入黑名单。

Why is my subscriber not invoked from in the EDT the second time around? 为什么第二次不在EDT中调用我的订户?

No. Event Admin does not guarantee which thread the event will be delivered on, and it is pretty much certain NOT to be the original sending thread. 不可以。事件管理员不能保证事件将在哪个线程上传递,并且可以肯定不是原始发送线程。

Since your handler does not know what thread it is on, it cannot directly manipulate the GUI. 由于您的处理程序不知道它在哪个线程上,因此它无法直接操作GUI。 Instead it must use SwingUtilities.invokeLater() to push a Runnable onto the event queue, and in that Runnable you can make the GUI changes. 相反,它必须使用SwingUtilities.invokeLater()将Runnable推入事件队列,并且可以在该Runnable中进行GUI更改。 For example: 例如:

class MyEventHandler implements EventHandler {
    public void handleEvent(final Event event) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // here you can make the UI changes in response to the event data
            }
        });
    }
}

EventAdmin spec does not require the event be delivered on the same thread that it was published. EventAdmin规范不需要在发布事件的同一线程上传递事件。 You would need to use an EventAdmin implementation which added this guarantee since you must receive the event on the same thread that it was published. 您将需要使用添加了此保证的EventAdmin实现,因为必须在发布事件的同一线程上接收该事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM