使用命名锁(例如,键名)同步对范围和结构的特定键的读/写访问是否安全?我已经做了一段时间了,从没有遇到并发问题,但是我正在编写服务器级缓存,并且我想确保基于名称的锁定在server
范围内是安全的。恐怕基础实现可能不是线程安全的,并且对不同键的并发访问可能会导致问题。
答案 0 :(得分:1)
通过cflock
锁定ColdFusion只是semaphores。它们控制哪些线程可以同时(并发)访问代码。这些锁不会影响Java的固有锁或同步的方法/语句。因此cflock
本身并不提供线程安全。
用户Ageax显示CF结构未使用ConcurrentHashMap(请参见注释),因此您必须明确使用它们:createObject("java", "java.util.concurrent.ConcurrentHashMap").init()
请注意,ConcurrentHashMap是类型且区分大小写(而常规结构则不区分大小写)。
ColdFusion中的结构本质上是线程安全的。这是一个比较不安全的Java HashMap和安全的ColdFusion Struct的示例:
首次使用:
<cfset s = createObject("java", "java.util.HashMap").init()>
第二次运行:
<cfset s = structNew()>
<cfset s.put("A", 1)>
<cfset s.put("B", 2)>
<cfthread name="interrupter">
<cfset s.put("C", 3)>
</cfthread>
<cfoutput>
<cfloop collection="#s#" item="key">
#s[key]#,
<cfset sleep(1000)>
</cfloop>
#structKeyList(s)#
</cfoutput>
HashMap将抛出ConcurrentModificationException
,因为主线程访问了地图,而“中断者”线程对其进行了修改。
但是,结构不会引发异常。由于迭代器阻止访问,即会导致“中断器”线程的写操作被推迟,因此它只会返回1,2,A,B,C
。迭代器完成后(循环结束),它将释放锁定,并且将修改结构。这就是structKeyList()
也将立即返回新编写的键值对"C": 3
的原因。
您可以在java.util.concurrent.ConcurrentHashMap的官方Java文档中详细了解并发映射访问的实现细节。但是请记住,ColdFusion可能使用了ConcurrentHashMap的派生版本。