这段代码中是否存在AtomicBoolean矫枉过正?

时间:2016-03-01 12:31:35

标签: java javafx

以下是我编写的一些代码,用于以通用方式处理事件处理程序,该事件处理程序仅对任何JavaFX事件触发一次:

public final class OneShotEvent<T extends Event>
    implements EventHandler<T>
{
    private final AtomicBoolean triggered = new AtomicBoolean(false);
    private final EventHandler<T> delegate;

    public static <E extends Event> EventHandler<E> of(final EventHandler<E> delegate)
    {
        return new OneShotEvent<>(delegate);
    }

    private OneShotEvent(final EventHandler<T> delegate)
    {
        this.delegate = Objects.requireNonNull(delegate);
    }

    @Override
    public void handle(final T event)
    {
        if (!triggered.getAndSet(true))
            delegate.handle(event);
    }
}

出于某种原因,我将triggered改为AtomicBoolean而不是普通boolean

在考虑之后,我认为这是过度的,因为事件处理程序将在JavaFX的“平台线程”上运行......或者他们不会? 因为如果是这种情况,那么一个简单的布尔就足够了......对吗?

3 个答案:

答案 0 :(得分:3)

如果你知道调用是单线程或线程安全的,那么一个简单的布尔就足够了,不过你可以放弃它。

private EventHandler<T> delegate;

public void handle(T event) {
    if (delegate != null)
        delegate.handle(event);
    delegate = null; // don't retain a delegate we don't need
}

答案 1 :(得分:2)

  

在考虑之后,我认为这是矫枉过正,因为事件处理程序将在&#34;平台线程上运行&#34; JavaFX ...或者他们不会吗?

是的,他们会:

  
    

The JavaFX scene graph, which represents the graphical user interface of a JavaFX application, is not thread-safe and can only be accessed and modified from the UI thread also known as the JavaFX Application thread.

  

答案 2 :(得分:0)

如果您确定事件处理程序在应用程序线程上运行,则您不需要关心线程安全。

但是,事件也可以在非应用程序线程上运行。 触发事件的线程也是运行事件处理程序的线程。

您可以使用以下代码进行演示,这些代码甚至无法启动应用程序线程:

public class EventThreadsTest {

    public static void main(String[] args) {
        Thread t = Thread.currentThread();
        EventHandler handler = (evt) -> {
            System.out.println("Application thread: " + Platform.isFxApplicationThread());
            System.out.println("main thread: " + Thread.currentThread() == t);
        };
        Node target = new Pane();
        target.setOnMouseClicked(handler);
        target.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, MouseButton.PRIMARY, 1, true, true, true, true, true, true, true, true, true, true, null));
    }

}

输出:

Application thread: false
main thread: true

然而,由用户交互触发的Button.onActionNode.onMouseClicked等UI事件在应用程序线程上运行。