此方法为什么会有并发问题?已加锁,依然会有并发覆盖,(出错位置为,多个线程操作同一Session)
(该方法功能为文件分片创建临时文件对象,并将文件对象保存到当前session中,以便于分片合并,问题出在当流程走chunks分支,操作session时会出现并发问题;当加锁时,应当会锁住当前对象;这个方法实现类取自springmvc容器,为单例对象,理论上同一时刻只会有一个线程才能取得这个锁,个人理解应当不会出现并发问题,不知道是不是哪个地方没有想到?希望高人指点
flag含义:chunks:为分片创建文件;single:为单文件(不需要切片)创建文件,merging:为合并分片创建文件;tempWorkPath:分片临时保存目录地址;saveFilePath:最终文件保存地址)

@Override
synchronized public File GenerateDirPathForCurrFile(MutilFileInfo fileinfo,String flag) throws Exception {
String fileName = fileinfo.getName();
String lastModifiedDate = fileinfo.getLastModifiedDate();
String fileSize = fileinfo.getSize();
String type = fileinfo.getType();
String id = fileinfo.getId();
long timeStemp=System.currentTimeMillis();
if("single".equals(flag)||"merging".equals(flag)) {
String extName = fileName.substring(fileName.lastIndexOf("."));
String fileNameSource = fileName+lastModifiedDate+fileSize+type+id+timeStemp;
String fileDirName = SHA256Util.getSHA256StrJava(fileNameSource)+extName;
File targetFile = new File(saveFilePath,fileDirName);
while(targetFile.exists()){
fileNameSource=fileNameSource+"1";
fileDirName = SHA256Util.getSHA256StrJava(fileNameSource)+extName;
targetFile = new File(fileDirName);
}
return targetFile;
}else if("chunks".equals(flag)) {
String fileNameSource = tempWorkPath+"/"+timeStemp+"_"+fileName+"_"+"part"+fileinfo.getChunk();
File tempFile = new File(fileNameSource);
fileinfo.setFileChunk(tempFile);
if(SessionUtils.getSessionAttribute("fileChunks")==null){
//fileChunksMapLock.lock();//此处加锁,防止并发创建时fileChunks中数据被覆盖
if(SessionUtils.getSessionAttribute("fileChunks")==null){
ConcurrentHashMap<String, Object> fileChunksMap = new ConcurrentHashMap<>();
SessionUtils.setSessionAttribute("fileChunks", fileChunksMap);
System.out.println("创建fileChunksMaps==========");
}
//fileChunksMapLock.unlock();//释放锁
}
ConcurrentHashMap<String, Object> fileChunksMap = (ConcurrentHashMap<String, Object>) SessionUtils.getSessionAttribute("fileChunks");
if(fileChunksMap.get(id+fileName)==null){
//chunksArrLock.lock();//此处加锁,防止并发创建时chunksArr中数据被覆盖
if(fileChunksMap.get(id+fileName)==null){
//MutilFileInfo[] chunksArr = new MutilFileInfo[fileinfo.getChunks()];
List<MutilFileInfo> chunksArr=Collections.synchronizedList(new ArrayList<>());
fileChunksMap.put(id+fileName, chunksArr);
System.out.println("创建fileChunksArr==========");
}
//chunksArrLock.unlock();//释放锁
}
@SuppressWarnings("unchecked")
List<MutilFileInfo> chunksArr = (List<MutilFileInfo>) fileChunksMap.get(id+fileName);
chunksArr.add(fileinfo);
System.out.println("添加fileinfo:"+fileinfo);
return tempFile;
}else{
throw new Exception("目标文件生成失败");
}
}来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2370/viewspace-3165280/ ,如需转载,请注明出处,否则将追究法律责任。