如果我的代码完全是在Platform.runLater
内部运行的,那么代码是否自动线程安全?
我的理解是,在Platform.runLater
上运行的代码在JavaFX应用程序线程上运行,该线程只有一个。
例如,如果我完全在Plaform.runLater
中操作哈希映射,则不必担心多个线程,对吗?
答案 0 :(得分:3)
是否使用Platform#runLater(Runnable)
是线程安全的,这完全取决于您的使用方式。您给出的示例是您有一个Map
从后台线程可见,但是只能通过runLater
在 JavaFX Application Thread 上对其进行操作。也许像这样:
// executing on background thread
Object newKey = ...;
Object newVal = ...;
Platform.runLater(() -> map.put(newKey, newVal));
仅从 JavaFX Application Thread 的角度来看,这使Map
是“线程安全的”。如果后台线程稍后尝试读取Map
(例如map.get(newKey)
),则不能保证该线程将看到新条目。换句话说,它可能会读取null
,因为条目“不存在”,或者它可能会读取旧值(如果已经存在)。您当然也可以通过阅读 JavaFX Application Thread 来解决此问题:
Object val = CompletableFuture.supplyAsync(() -> map.get(key), Platform::runLater).join();
或者甚至通过等待 JavaFX Application Thread 完成对Map
的写入:
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
// write to map
latch.countDown();
});
latch.await();
// writes to map will be visible to background thread from here
也就是说, JavaFX应用程序线程将看到在调用runLater
之前发生的后台线程的操作。换句话说,创建了一个Runnable
在 JavaFX Application Thread 上执行时,最终必须发生一些线程间通信,这又需要同步才能保证线程安全。在JavaFX的Windows实现上,我无法确定这种同步是什么样的,因为它似乎调用了本机方法。