2016-03-01 122 views
3

下面是一些代碼,我已經寫在一個通用的方式來處理事件,其應僅用於任何JavaFX的事件觸發一次:在這段代碼中AtomicBoolean矯枉過正?

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的「平臺線程」上運行......或者它們不會? 因爲如果是這種情況,那麼一個簡單的布爾值就足夠了......對嗎?

+0

在多線程環境中,這將是一個體面的模式使用。在單線程環境中確實是一個矯枉過正的問題,但你應該擺脫它的原因不是性能,而是代碼複雜性。 – biziclop

+0

@biziclop我同意。我現在只是沒有足夠的信心,因爲我對JavaFX的瞭解最多隻有一個簡單的布爾值「足夠安全」:( – fge

回答

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 
} 
+3

我討厭nulls:p – fge

+2

@fge這不是愛與恨的問題。這種情況下,將'委託'清空是有意義的,考慮一下如果它保留了一個大的對象圖,會發生什麼。 – biziclop

+0

@biziclop不夠公平......儘管我會質疑這樣一個事件處理程序的完整性,以開始:) – fge

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事件由用戶觸發交互在應用程序線程上運行。

+0

嗯,這個類_is_意味着在「JavaFX上下文」中使用...... – fge

+0

@fge:這並不妨礙你在你的JavaFX應用程序中啓動一個觸發事件的newad但是......爲了完整起見,我只想補充一點... – fabian

相關問題