我正在尝试从数据库同步硬盘上的文件兑现.
我正在检查文件是否存在,如果不存在,我从数据库中获取文件并进行部署.由于Race条件,我不想多次写文件.
这是我制作的代码:
重要提示:此代码位于Bean内部,具有其所有含义
Run Code Online (Sandbox Code Playgroud)@Override public String getThumbnailPictureUrl(Design design) { String relativePath = String.format(THUMBNAIL_URL, design.getId(), design.getThumbnailPicture().getFileName()); String realPath = servletContext.getRealPath("/"+relativePath); logger.info("Request Thumbnail picture for design: " + design.getId()); logger.info("Thumbnail picture relative path: " + relativePath); logger.info("Thumbnail picture real path: " + realPath); File file = new File(realPath); if(!file.exists()) { synchronized (thumbnailLock) { if(!file.exists()) { logger.warn("Could not fild file in path: " + realPath); FileAttachment pictureAttachment = design.getThumbnailPicture(); Hibernate.initialize(pictureAttachment.getAttachment()); Data data = (Data) pictureAttachment.getAttachment(); file = toolBox.convertBlobToFile(data.getBlob(), file); logger.warn("file created in path: " + realPath); } } } return relativePath; }
有了这个解决方案,我找不到文件,我真的不会写文件2次以及任何其他文件,因为我正在同步整个块,所有线程试图到达它,即使是要写一个不同的文件.
有什么建议?
谢谢.
与@ Avi的解决方案类似,但使用ConcurrentHashMap.
private final ConcurrentMap<String, Object> map = new ConcurrentHashMap<>();
String name = file.getName();
Object lock = map.get(name);
if (lock == null) {
map.putIfAbsent(name, new Object());
lock = map.get(name);
}
synchronized (lock) {
// do something
}
map.remove(name);
Run Code Online (Sandbox Code Playgroud)
创建一个 of 锁怎么样HashMap
?键将是文件路径,值将只是用作锁的对象。假设这张地图的定义如下:
Map<String, Object> locks = new Map<String, Object>();
Run Code Online (Sandbox Code Playgroud)
这就是用途:
if(!file.exists())
{
Object lock = null;
synchronized (locks) {
lock = locks.get(file.getName());
if(lock == null) {
lock = new Object();
locks.put(file.getName(), lock);
}
}
synchronized (lock)
{
if(!file.exists())
{
logger.warn("Could not fild file in path: " + realPath);
FileAttachment pictureAttachment = design.getThumbnailPicture();
Hibernate.initialize(pictureAttachment.getAttachment());
Data data = (Data) pictureAttachment.getAttachment();
file = toolBox.convertBlobToFile(data.getBlob(), file);
logger.warn("file created in path: " + realPath);
}
}
synchronized(locks) {
map.remove(lock));
}
}
Run Code Online (Sandbox Code Playgroud)