在多线程写文件的时候,未保证写入的数据不会乱掉,有时需要控制多线程写入的顺序
@Override
public void write(List<? extends MyFileWriteDTO> items) {
/**
* 文件写入以追加的方式写入数据,注意线程安全问题
*/
logger.info("current threadName ==[{}] ", currentThread().getName());
FileOutputStream fos = null;
FileChannel fc = null;
FileLock fl = null;
try {
//Constants.COPY_DEVICE_DATA_FILE_PATH 文件路径
fos = new FileOutputStream(Constants.COPY_DEVICE_DATA_FILE_PATH, true);
fc = fos.getChannel();
while (true) {
try {
fl = fc.tryLock();//不断的请求锁,如果请求不到,等一秒再请求
break;
} catch (Exception e) {
logger.info("lock is exist ...... current threadName ==[{}]", currentThread().getName());
sleep(1000);//睡1s
}
}
StringBuffer sb = new StringBuffer();
//处理数据
byte[] bytes = sb.toString().getBytes();
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
buffer.clear();
buffer.put(bytes);
buffer.flip();
fc.write(buffer);
logger.info("current threadName ==[{}] write success", currentThread().getName());
fl.release();
logger.info("current threadName ==[{}] release lock", currentThread().getName());
fc.close();
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
logger.error("current threadName ==[{}] write failed", currentThread().getName());
} finally {
if (fl != null && fl.isValid()) {
try {
fl.release();
} catch (IOException e) {
e.printStackTrace();
logger.error("current threadName ==[{}] release failed", currentThread().getName());
}
}
}
}