java - Ref to map vs. map to refs vs. multiple refs

标签 java data-structures concurrency clojure state

我正在使用 Swing+Clojure 开发一个 GUI 应用程序,它需要各种可变数据(例如滚动位置、用户数据、文件名、选定的工具选项等)。

我至少可以看到三种不同的处理这组数据的方式:

创建对所有数据的映射的引用:

(def data (ref {
  :filename    "filename.xml" 
  :scroll      [0 0] }))

创建单个数据元素的引用映射:

(def datamap {
  :filename    (ref "filename.xml") 
  :scroll      (ref [0 0]) }))

为命名空间中的每个创建一个单独的引用:

(def scroll (ref [0 0]))    

(def filename (ref "filename.xml"))

注意:此数据将被同时访问,例如通过后台处理线程或 Swing 事件处理线程。但是,可能不需要对多个元素进行一致的事务更新。

您推荐的方法是什么?为什么?

最佳答案

首先,如果您最终只使用一个可变状态或几个独立的部分(独立的,如“询问一个与另一个是否一致是没有意义的”),为什么不使用 Atoms 而不是 Refs?这大大减少了开销,如果您进行大量更新,这实际上可能很重要。

其次,将文件名、滚动位置等存储在单独的 Refs(但不是 Atoms)中是可以的,只要你仔细设计你的事务(即需要提及所有相关的 Refs,有些可能需要确保d 等——基本上,如果出现不一致状态,事务必须确保失败)。如果您正在管理 GUI 状态,其中大部分几乎不会改变(除了滚动位置和缓冲区内容,实际上可能经常改变的是什么? - 我的意思是这是需要认真考虑的事情,那么仔细设计此类事务可能会浪费精力,因为答案应该决定最终的设计)。在许多情况下,拥有多个引用类型对象比拥有一个更可取,我只是不确定管理基本 GUI 状态是其中之一。 :-)

请注意,对引用类型对象中的嵌套结构执行更新在 Clojure 中非常干净,例如(使用 Atom):

;; assuming that state-o-matic is an Atom which holds a map,
;; which holds the key of :foo, with which a vector is associated,
;; whose first item is another vector, whose first item is a map
;; which holds the key of :bar associated to a number,
;; the following increments said number
(swap! state-o-matic update-in [:foo 0 1 :bar] inc)

另请参阅get-inassoc-in

关于java - Ref to map vs. map to refs vs. multiple refs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3056825/

相关文章:

java - Hibernate 是否必须驱动数据库设计?

java - C++ 到 Java - OpenCV

c++ - 哈希表——哈希函数实现

multithreading - 如何使用Data.Concurrent.mergeIO?

java - Spring Boot 冷启动

java - 如何连接线程被销毁的那一刻

java - 如果我想根据不同的属性以不同的方式搜索一个对象,应该使用什么数据结构?

algorithm - 如何有效地找到集合的所有存储子集? (关联规则查找)

php - postgresql 事务并发测试脚本

Python 多处理 block 在 waiter.acquire() 中不确定