java中安全的多线程文件创建
我有一个 web 应用程序,有时需要从 url 下载一些字节并将其打包并发回给请求者。下载的字节会存储一段时间,以便在需要下载相同的 URL 时可以重复使用它们。我试图找出如何最好地防止线程同时下载相同的 url(如果请求同时传入)。我正在考虑创建一个如下所示的类,以防止同时下载相同的网址。如果一个 url 无法被锁定,那么它要么等到它不再被锁定,然后尝试下载它,只要它在解锁后不存在。
public class URLDownloader
{
HashMap<String,String> activeThreads = new HashMap<String,String>();
public synchronized void lockURL(String url, String threadID) throws UnableToLockURLException
{
if(!activeThreads.containsKey(url))
activeThreads.put(url, threadID)
else
throw UnableToLockURLException()
}
public synchonized void unlockURL(String url, String threadID)
{
//need to check to make sure its locked and by the passed in thread
returns activeThreads.remove(url);
}
public synchonized void isURLStillLocked(String url)
{
returns activeThreads.contains(url);
}
}
有人对此有更好的解决方案吗?我的解决方案看起来有效吗?是否有任何开源组件已经可以很好地做到这一点,我可以利用?
谢谢
I have a webapp that needs to sometimes download some bytes from a url and package it up and send back to the requester. The downloaded bytes are stored for a little while so they can be reused if the same url is needed to be downloaded. I am trying to figure out how best to prevent the threads from downloading the same url at the same time if the requests come in at the same time. I was thinking of creating a class like below that would prevent the same url from being downloaded at the same time. If a url is unable to be locked then it either waits until its not locked anymore to try and download it as long as it does not exist after the unlock.
public class URLDownloader
{
HashMap<String,String> activeThreads = new HashMap<String,String>();
public synchronized void lockURL(String url, String threadID) throws UnableToLockURLException
{
if(!activeThreads.containsKey(url))
activeThreads.put(url, threadID)
else
throw UnableToLockURLException()
}
public synchonized void unlockURL(String url, String threadID)
{
//need to check to make sure its locked and by the passed in thread
returns activeThreads.remove(url);
}
public synchonized void isURLStillLocked(String url)
{
returns activeThreads.contains(url);
}
}
Does anyone have a better solution for this? Does my solution seem valid? Are there any open source components out there that already do this very well that I can leverage?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议保留一个())
ConcurrentHashSet
来跟踪所有线程可见的唯一 URL。此构造可能不直接存在于 java 库中,但可以通过 ConcurrentHashMap 轻松构造,如下所示:Collections.newSetFromMap(new ConcurrentHashMapI would suggest to keep a
ConcurrentHashSet<String>
to keep track of your unique URLs visible to all your threads. This construct might not exist directly in the java library but can easily constructed by a ConcurrentHashMap like so:Collections.newSetFromMap(new ConcurrentHashMap<String,Boolean>())
听起来你不需要锁,因为如果有多个请求下载同一个 URL,那么重点就是只下载一次。
另外,我认为就封装而言,将检查存储的 URL/例程以将新 URL 存储在
URLDownloader
类中而不是在调用类中更有意义。您的线程可以简单地调用例如fetchURL()
,并让URLDownloader
处理具体细节。因此,您可以通过两种方式实现这一点。如果您没有源源不断的下载请求,更简单的方法是仅运行一个
URLDownloader
线程,并使其fetchURL
方法同步< /code>,这样您一次只能下载一个 URL。否则,将待处理的下载请求保留在中央
LinkedHashSet
中,这会保留顺序并忽略重复。It sounds like you don't need a lock, since if there are multiple requests to download the same URL, the point is to download it only once.
Also, I think it would make more sense in terms of encapsulation to put the check for a stored URL / routine to store new URLs in the
URLDownloader
class, rather than in the calling classes. Your threads can simply call e.g.fetchURL()
, and letURLDownloader
handle the specifics.So, you can implement this in two ways. If you don't have a constant stream of download requests, the simpler way is to have only one
URLDownloader
thread running, and to make itsfetchURL
methodsynchronized
, so that you only download one URL at a time. Otherwise, keep the pending download requests in a centralLinkedHashSet<String>
, which preserves order and ignores repeats.