Java 避免线程交叉
我有这个方法:Java 避免线程交叉,java,multithreading,Java,Multithreading,我有这个方法: GenericDatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema); ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
GenericDatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(baos, null);
public void WriteToFile(Record record) {
this.baos.reset();
try (FileOutputStream fileOut = new FileOutputStream(avroFile, true)) {
datumWriter.write(record, encoder);
encoder.flush();
fileOut.write("RecordStart\n".getBytes());
baos.writeTo(fileOut);
fileOut.write("\nRecordEnd\n".getBytes());
this.baos.flush();
} catch (IOException e) {
logger.error("Error while writing: ", e);
}
}
GenericDatumWriter datumWriter=新的GenericDatumWriter(模式);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
BinaryEncoder编码器=EncoderFactory.get().BinaryEncoder(baos,null);
公共无效写入文件(记录){
这个.baos.reset();
try(FileOutputStream fileOut=newfileoutputstream(avroFile,true)){
datumWriter.write(记录、编码器);
encoder.flush();
write(“RecordStart\n”.getBytes());
资产负债表(备案);
fileOut.write(“\nRecordEnd\n”.getBytes());
this.baos.flush();
}捕获(IOE异常){
logger.error(“写入时出错:”,e);
}
}
上述方法由多个线程调用,每个线程将在RecordStart
和RecordEnd
之间写入一条record
,可能出现日志交错的情况,即我们将无法在RecordStart
和RecordEnd
之间获取记录
因此,为了避免这种情况,一种解决方案是使用synchronized
,但这会导致性能问题,因为我们让线程等待
因此,我想提出一些建议,这样我们就可以避免多个线程同时写入同一个文件,这可能会导致日志交错?只有当您的操作可以并行时,您才能从并行处理中获益。我的意思是:
若您正在写入一个文件,这个特定的计算步骤必须同步完成,可以是通过
synchronized
或通过file lock,否则您将得到加扰的数据
要提高性能,您可以做的是:尽可能减少同步/锁定块,将最后一步(写入)仅保留在同步或锁定块上。除此之外,您还可以写入多个文件
我更喜欢使用文件锁,因为它将使方法更通用。如果您决定扩展它,那么它可以用来编写多个文件。此外,它还避免了同时使用文件的其他过程(程序除外)
看看这个问题
回答具体问题: 所以我想要一些建议,这样我们可以避免多个线程同时写入同一个文件,这可能会导致日志交错 在不损失性能的情况下。。。我认为没有办法。写入文件的本质要求它是连续的
我见过的大多数系统都将所有日志写入一个文件,使用一个队列和一种方法,在队列能够提供,因此,只要系统不断接收的记录不超过磁盘所能管理的数量,所有内容最终都会被写入。只有当操作可以并行化时,才能从并行处理中获益。我的意思是:
若您正在写入一个文件,这个特定的计算步骤必须同步完成,可以是通过
synchronized
或通过file lock,否则您将得到加扰的数据
要提高性能,您可以做的是:尽可能减少同步/锁定块,将最后一步(写入)仅保留在同步或锁定块上。除此之外,您还可以写入多个文件
我更喜欢使用文件锁,因为它将使方法更通用。如果您决定扩展它,那么它可以用来编写多个文件。此外,它还避免了同时使用文件的其他过程(程序除外)
看看这个问题
回答具体问题: 所以我想要一些建议,这样我们可以避免多个线程同时写入同一个文件,这可能会导致日志交错 在不损失性能的情况下。。。我认为没有办法。写入文件的本质要求它是连续的
我见过的大多数系统都将所有日志写入一个文件,使用一个队列和一种方法,在队列能够提供,因此,只要系统持续接收的记录不超过磁盘所能管理的数量,所有内容最终都会被写入。它与使用
synchronized
有什么不同,线程将等待文件解锁,对吗?我将编辑答案以澄清文件锁是由整个进程拥有的,因此它对控制多线程访问没有帮助。显示它与使用synchronized
不同,线程将等待文件解锁,对吗?我将编辑答案以澄清文件锁定是由整个进程拥有的,因此它对控制多线程访问没有帮助这对您有帮助吗?创建一个POJO对象并将其用作锁定机制:设置锁,强制其他线程等待、修改或写入记录,然后最终向所有线程发出通知,以便等待的线程可以开始竞争。这对您有帮助吗?创建一个POJO对象并将其用作锁定机制:设置锁,强制其他线程等待它、修改或写入记录,然后最终向所有线程发出通知,以便等待的线程可以开始竞争。