<cflock name =“ ...”>使用范围和结构锁定安全吗?

时间:2019-08-28 13:17:48

标签: concurrency coldfusion locking

使用命名锁(例如,键名)同步对范围和结构的特定键的读/写访问是否安全?我已经做了一段时间了,从没有遇到并发问题,但是我正在编写服务器级缓存,并且我想确保基于名称的锁定在server范围内是安全的。恐怕基础实现可能不是线程安全的,并且对不同键的并发访问可能会导致问题。

1 个答案:

答案 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的派生版本。