[英]Java file locking way by multiple threads as well as multiple processes
我有3个以上的Java进程访问同一文件进行读写。 每个进程都有多个线程,这些线程非常频繁地读写文件(在1秒钟内大约10倍的速率)。
我正在使用java.nio.channels.FileLock
进行进程间文件锁定。 和commonObj.wait()
commonObj.notify()
用于线程间同步。
我在此实施过程中面临的问题是-
java.io.IOException: Resource deadlock avoided
异常发生的过程之一。 我的问题是
我已经为所有Java进程编写了通用的Reader writer类。 附加相同。
package json_file_handler; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.channels.OverlappingFileLockException; import java.util.concurrent.locks.ReentrantLock; import org.apache.log4j.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JsonReader { final static Logger logger = Logger.getLogger(JsonReader.class); static final ReentrantLock relock = new ReentrantLock(); /** * Read given file in JSONObject * @param fileName String * @return JSONObject */ @SuppressWarnings("resource") public static JSONObject readJsonFile(String fileName) { JSONObject createdJsonObj = null; JSONParser jsonParser = new JSONParser(); FileChannel channel = null; FileLock lock = null; FileReader fileReader = null; boolean islocked = false; try { while(!islocked) { try { File file = new File(fileName); channel = new RandomAccessFile(file, "rw").getChannel(); lock = channel.lock(); if(lock != null) { islocked = true; fileReader = new FileReader(fileName); createdJsonObj = (JSONObject) jsonParser.parse(fileReader); } } catch(OverlappingFileLockException e) { logger.error("FILE LOCK OVERLAP EXP OCCURED IN READING FILE " + fileName +". ATTEMPTING TO READ FILE AGAIN."); //Thread.sleep(1); //release the lock if(lock != null) { lock.release(); } // close the channel if(channel != null) { channel.close(); } synchronized (relock) { relock.wait(); } } } //while } catch (FileNotFoundException e) { e.printStackTrace(); logger.error("FILE NOT FOUND ERROR IN READING JSON FOR FILE NAMED "+fileName+".",e); } catch (IOException e) { e.printStackTrace(); logger.error("IO ERROR IN READING JSON FOR FILE NAMED "+fileName+".",e); } catch (ParseException e) { e.printStackTrace(); logger.error("PARSING ERROR IN JSON FOR FILE NAMED "+fileName+".",e); } catch (Exception e) { e.printStackTrace(); logger.error("ERROR IN JSON FOR FILE NAMED "+fileName+".",e); } finally { try { if(fileReader != null) { fileReader.close(); } // release the lock if(lock != null) lock.release(); // close the channel if(channel != null) { channel.close(); } } catch (IOException e) { e.printStackTrace(); logger.error("IO ERROR IN CLOSING FILE "+fileName+".",e); } catch (Exception e) { e.printStackTrace(); logger.error("ERROR IN CLOSING FILE "+fileName+".",e); } finally { synchronized (relock) { relock.notify(); } } } return createdJsonObj; } }
package json_file_handler; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.nio.channels.OverlappingFileLockException; import org.apache.log4j.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class JsonWriter { final static Logger logger = Logger.getLogger(JsonWriter.class); /** * Write given JSONObject into given file name * @param fileName String * @param ObjToWrite JSONObejct * @return boolean true on success else false */ @SuppressWarnings("resource") public static boolean writeJsonFile(String fileName, JSONObject ObjToWrite) { boolean writeFlag = false; FileChannel channel = null; FileLock lock = null; FileWriter fileWriter = null; boolean islocked = false; try { while(!islocked) { try { File file = new File(fileName); channel = new RandomAccessFile(file, "rw").getChannel(); lock = channel.lock(); if(lock != null) { islocked = true; fileWriter = new FileWriter(fileName); Gson gson2 = new GsonBuilder().setPrettyPrinting().create(); String json2 = gson2.toJson(ObjToWrite); fileWriter.write(json2); writeFlag = true; } } catch(OverlappingFileLockException e) { logger.error("FILE LOCK OVERLAP EXP OCCURED IN WRITING FILE " + fileName +". ATTEMPTING TO WRITE FILE AGAIN."); //release the lock if(lock != null) { lock.release(); } // close the channel if(channel != null) { channel.close(); } synchronized (JsonReader.relock) { JsonReader.relock.wait(); } } } } catch (FileNotFoundException e) { e.printStackTrace(); logger.error("FILE NOT FOUND ERROR IN WRITING JSON FOR FILE NAMED "+fileName+".",e); } catch (IOException e) { e.printStackTrace(); logger.error("IO ERROR IN WRITING JSON FOR FILE NAMED "+fileName+".",e); } catch (Exception e) { e.printStackTrace(); logger.error("ERROR IN JSON FOR FILE NAMED "+fileName+".",e); } finally { try { if(fileWriter != null) { fileWriter.flush(); fileWriter.close(); } // release the lock if(lock != null) lock.release(); // close the channel if(channel != null) { channel.close(); } } catch (IOException e) { e.printStackTrace(); logger.error("IO ERROR IN CLOSING FILE "+fileName+".",e); } catch (Exception e) { e.printStackTrace(); logger.error("ERROR IN CLOSING FILE "+fileName+".",e); } finally { synchronized (JsonReader.relock) { JsonReader.relock.notify(); } } } return writeFlag; } }
我认为您正在Linux上运行此程序。 Java将(主要)使用POSIX锁http://www.man7.org/linux/man-pages/man2/fcntl.2.html
请参阅手册中提及EDEADLK的部分。 linux操作系统很可能无法识别在同一个JVM中正在运行2个不同的线程。 请参阅https://gist.github.com/harrah/4714661此处的类似示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.