![](/img/trans.png)
[英]What's the risk if I replace AtomicBoolean with volatile in this code?
[英]Is an AtomicBoolean overkill in this code?
下面是我編寫的一些代碼,用於以通用方式處理一個事件處理程序,它只能為任何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的“平台線程”上運行......或者他們不會? 因為如果是這種情況,那么一個簡單的布爾就夠了......對嗎?
如果你知道調用是單線程或線程安全的,那么一個簡單的布爾就足夠了,盡管你可以放棄它。
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
}
在考慮之后,我認為這是過度的,因為事件處理程序將在JavaFX的“平台線程”上運行......或者他們不會?
是他們會:
JavaFX場景圖表示JavaFX應用程序的圖形用戶界面,它不是線程安全的,只能從UI線程(也稱為JavaFX Application線程)訪問和修改。
如果您確定事件處理程序在應用程序線程上運行,則無需關心線程安全性。
但是,事件也可以在非應用程序線程上運行。 觸發事件的線程也是運行事件處理程序的線程。
您可以使用以下代碼演示此內容,甚至不啟動應用程序線程:
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
但是,由用戶交互觸發的UI事件(如Button.onAction
和Node.onMouseClicked
在應用程序線程上運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.