Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免线程交叉_Java_Multithreading - Fatal编程技术网

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对象并将其用作锁定机制:设置锁,强制其他线程等待它、修改或写入记录,然后最终向所有线程发出通知,以便等待的线程可以开始竞争。