我有一个链接,允许用户点击它,它会获取一个zip文件的照片。如果zip文件不存在,则它会启动一个线程来创建zip,并向用户显示当前正在处理照片的消息。
我要避免的是用户反复点击链接并设置将尝试创建/更新zip文件的大量线程。 zip文件处理非常耗费系统资源,所以我只想让应用程序一次生成一个zip。如果一个忙于编译,它应该什么都不做并排队请求。
目前我正在处理它的方法是在线程周围使用cflock:
<cflock name="createAlbumZip" type="exclusive" timeout="30" throwontimeout="no">
<cfthread action="run" albumId="#arguments.albumId#" name="#CreateUUID()#">
....
我希望在这里发生(如果我测试它似乎工作)是它将检查当前是否正在使用名为'createAlbumZip'的锁运行一个线程。如果有,它会将请求排队30秒,之后它应该超时而没有任何错误。如果它无法在30秒内创建它,那很好。
所以 - 这似乎有效,但我的问题是:这是处理这种情况的最佳方法吗?锁定正确的方法?我没有看到这种方法可能产生的任何缺点吗?
答案 0 :(得分:2)
有一百万种皮肤养猫的方法。锁定是一个良好的开端,根据你对@Pat Branley的回答的评论,我认为你在线程创建之外的锁定可能会因为你提出的原因更有效:创建数十个线程的潜力将存在于整个生命周期中将包括等待锁定打开或超时。
您需要做的另一件事是加倍IF语句:
<cfif not (zip file exists)>
<cflock ...>
<cfif not (zip file exists)>
<cfthread>
...create zip...
</cfthread>
</cfif>
</cflock>
</cfif>
这将防止线程B在线程A创建zip时等待的情况,然后线程A完成,线程B继续重新创建/覆盖它。
此外,您可以考虑使用JavaScript来通过在点击按钮/链接后禁用按钮/链接来防止额外点击。
答案 1 :(得分:0)
我认为你的代码是错误的。你所说的是'只允许一个线程产生这个新线程'。现在这可能适用于你的情况,因为你设置了超时,没有人可以创建另一个线程,所以一次不能执行两个线程。
你想说的是'只允许一个帖子打个拉链'。所以我会这样做
<cfthread .... >
<cflock>
...zip....