我在我的CF应用程序中使用了双重检查锁定的版本(在我知道双重检查锁定之前)。
基本上,我检查一个物体是否存在。如果它不存在,我锁定(通常使用命名锁),在我尝试创建对象之前,我再次检查是否存在。我认为这是一种简洁的方法来阻止创建多个对象并停止在系统中过度锁定。
这似乎有效,因为没有过多的锁定,并且不会创建对象重复项。但是,我最近才知道Double Checked Locking dosn't work in Java,我不知道的是CF是否适用,因为CF线程和锁与本机Java线程和锁不完全相同。
答案 0 :(得分:6)
要添加Ben Doom所说的关于Java的内容,这在ColdFusion中是相当标准的做法,特别是在设置应用程序变量的应用程序初始化例程中。
如果没有至少一个锁,您可以让Web应用程序的初始命中同时初始化应用程序变量。这假设您的应用程序足够繁忙以保证这一点。只有在应用程序首次启动时您的应用程序繁忙时才会存在危险。
第一个锁定确保一次只有一个请求初始化变量。
嵌入在第一个锁中的第二个锁将检查以确保存在初始化代码末尾定义的变量,例如application.started。如果存在,则用户被踢出。
双锁模式已将我的皮肤保存在繁忙的站点上,但是,对于非常繁忙的站点,应用程序初始命中完成的请求队列可能会爬得太高,太快,并导致服务器崩溃。想法是,请求正在等待第一次命中,这是慢,然后第二次打破第一次cflock,并很快被拒绝。随着队列中成百上千的请求,每毫秒都在增长,它们都汇集到第一个cflock块。解决方案是在第一个cflock上设置一个非常低的超时,而不是抛出(或捕获并查看)锁定超时错误。
作为最后一点,我所描述的这种行为已经被Application.cfc的ColdFusion 7的onApplicationStart()方法弃用了。如果您正在使用onApplicationStart(),那么您不应该完全锁定应用程序初始化例程。 Application.cfc已经很好地锁定了。
总而言之,是的,双重检查锁定在ColdFusion中有效。它在某些情况下很有用,但做得对。我不知道它为什么工作的原理图而不是Java的线程模型,很可能是在ColdFusion服务器的后台手动检查某种查找表。
答案 1 :(得分:2)
Java是线程安全的,所以并不是因为你的锁不能工作,因为它们不是必需的。基本上,在CF 6+中,需要锁来防止竞争条件或创建/消除Java控制之外的对象(例如文件)。
答案 2 :(得分:0)
打开另外一罐蠕虫......
为什么不使用依赖注入库(如ColdSpring)来跟踪对象并防止循环依赖。