是否执行“双重检查锁定”? 在 ColdFusion 工作?
我在我的 CF 应用程序中使用了双重检查锁定的一个版本(在我知道什么是双重检查锁定之前)。
本质上,我检查一个对象是否存在。 如果它不存在,我会锁定(通常使用命名锁),并在尝试创建对象之前再次检查是否存在。 我认为这是停止创建多个对象并停止系统中过度锁定的好方法。
这似乎有效,因为没有过多的锁定并且不会创建对象重复项。 但是,我最近了解到 双重检查锁定不起作用Java,我不知道这在 CF 中是否成立,因为 CF 线程和锁与本机 Java 线程和锁不太一样。
I have used a version of double checked locking in my CF app (before I knew what double checked locking was).
Essentially, I check for the existance of an object. If it is not present, I lock (usually using a named lock) and before I try and create the object I check for existance again. I thought this was a neat way to stop multiple objects being created and stop excessive locking in the system.
This seems to work, in that there is not excessive locking and object duplicates don't get created. However, I have recently learned that Double Checked Locking dosn't work in Java, what I don't know is if this holds true in CF, seeing as CF threads and locks are not quite the same as native Java threads and locks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
补充一下 Ben Doom 关于 Java 的说法,这是 ColdFusion 中相当标准的做法,特别是在您设置应用程序变量的应用程序初始化例程中。
如果没有至少一个锁,您将让对 Web 应用程序的初始点击同时初始化应用程序变量。 这假设您的应用程序足够繁忙,足以保证这一点。 仅当您的应用程序在首次启动时正忙时,才会存在危险。
第一个锁确保一次只有一个请求初始化您的变量。
第二个锁嵌入第一个锁中,它将检查以确保初始化代码末尾定义的变量存在,例如 application.started。 如果存在,则该用户将被踢出。
双重锁定模式让我在繁忙的站点上免于麻烦,但是,对于非常繁忙的站点,应用程序初始命中完成的请求队列可能会爬得太高、太快,并导致服务器崩溃。 这个想法是,请求正在等待第一次命中,这很慢,然后第二个请求闯入第一个 cflock,并很快被拒绝。 队列中有成百上千个请求,每毫秒都在增长,它们都向下汇集到第一个 cflock 块。 解决方案是在第一个 cflock 上设置非常低的超时,并且不抛出(或捕获并回避)锁定超时错误。
最后一点,我描述的这种行为已被 Application.cfc 的 ColdFusion 7 的 onApplicationStart() 方法弃用。 如果您使用 onApplicationStart(),那么您根本不应该锁定应用程序初始化例程。 Application.cfc 已被很好地锁定。
总而言之,是的,双重检查锁定在 ColdFusion 中有效。 这在某些情况下很有帮助,但要正确执行。 我不知道它的工作原理与 Java 的线程模型相反,它很可能是在 ColdFusion 服务器后台手动检查某种查找表。
To add on to what Ben Doom said about Java, this is fairly standard practice in ColdFusion, specifically with an application initialization routine where you set up your application variables.
Without having at least one lock, you are letting the initial hits to your web application all initialize the application variables at the same time. This assumes that your application is busy enough to warrant this. The danger is only there if your application is busy at the time your application is first starting up.
The first lock makes sure only one request at a time initializes your variables.
The second lock, embedded within the first, will check to make sure a variable defined at the end of your initialization code exists, such as application.started. If it exists, the user is kicked out.
The double-locking pattern has saved my skin on busy sites, however, with VERY busy sites, the queue of requests for the application's initial hit to complete can climb too high, too quickly, and cause the server to crash. The idea is, the requests are waiting for the first hit, which is slow, then the second one breaks into the first cflock, and is quickly rejected. With hundreds or thousands of requests in the queue, growing every millisecond, they are all funneling down to the first cflock block. The solution is to set a very low timeout on the first cflock and not throw (or catch and duck) the lock timeout error.
As a final note, this behavior that I described has been deprecated with ColdFusion 7's onApplicationStart() method of your Application.cfc. If you are using onApplicationStart(), then you shouldn't be locking at all for your application init routine. Application.cfc is well locked already.
To conclude, yes, double-checked locking works in ColdFusion. It's helpful in a few certain circumstances, but do it right. I don't know the schematics of why it works as opposed to Java's threading model, chances are it's manually checking some sort of lookup table in the background of your ColdFusion server.
Java 是线程安全的,所以并不是说你的锁不起作用,而是它们没有必要。 基本上,在 CF 6+ 中,需要锁来防止竞争条件或创建/更改 Java 控制之外的对象(例如文件)。
Java is threadsafe, so it isn't so much that your locks won't work as that they aren't necessary. Basically, in CF 6+, locks are needed for preventing race conditions or creating/althering objects that exist outside Java's control (files, for example).
要打开另一个蠕虫罐头...
为什么不使用依赖注入库(例如 ColdSpring)来跟踪对象并防止循环依赖。
To open a whole other can of worms...
Why don't you use a Dependency Injection library, such as ColdSpring, to keep track of your objects and prevent circular dependencies.