Java VanillaChronicle的线程安全性
我正在使用VanillaChronicle将一些消息写入磁盘Java VanillaChronicle的线程安全性,java,chronicle,Java,Chronicle,我正在使用VanillaChronicle将一些消息写入磁盘 public final class ConcurrentPersister{ private final String location; private final Chronicle chronicle; private final ExcerptAppender writer; private final static int STRING_SIZE_OVERHEAD = 1000;
public final class ConcurrentPersister{
private final String location;
private final Chronicle chronicle;
private final ExcerptAppender writer;
private final static int STRING_SIZE_OVERHEAD = 1000;
private final static String FILE_DATE_FORMAT = "MM-dd-yyyy";
private final static String NAME = "ConcurrentPersister";
private final static Logger LOGGER = LoggerFactory.getLogger( NAME );
public ConcurrentPersister( String location, VanillaChronicleConfig config ){
this.chronicle = new VanillaChronicle( location );
this.writer = chronicle.createAppender();
}
public final void appendMessage( final String message ){
try{
long length = STRING_SIZE_OVERHEAD + message.length();
writer.startExcerpt( length );
writer.append( message );
writer.finish();
}catch( Exception e ){
LOGGER.warn("Failed to persist Message [{}]", message );
LOGGER.warn("Exception: ", e );
}
}
}
如上所示,如果从多个线程调用appendMessage(String message)方法,该方法是线程安全的吗
我在某处读到VanillaChronicle的append(字符串消息)是线程安全的。
但是,我认为startExcerpt()+append()+finish()的复合动作不是线程安全的,这是正确的吗
谢谢。您需要在这三个方法调用上同步writer<代码>附加(消息)可能是线程安全的,但是,正如您所说,如果多个线程通过同一个ConcurrentPersister实例访问该方法,那么对writer的三个单独的方法调用可能会发生冲突
public final class ConcurrentPersister{
private final String location;
private final Chronicle chronicle;
private final ExcerptAppender writer;
private final static int STRING_SIZE_OVERHEAD = 1000;
private final static String FILE_DATE_FORMAT = "MM-dd-yyyy";
private final static String NAME = "ConcurrentPersister";
private final static Logger LOGGER = LoggerFactory.getLogger( NAME );
public ConcurrentPersister( String location, VanillaChronicleConfig config ){
this.chronicle = new VanillaChronicle( location );
this.writer = chronicle.createAppender();
}
public final void appendMessage( final String message ){
try{
long length = STRING_SIZE_OVERHEAD + message.length();
synchronized(writer){
writer.startExcerpt( length );
writer.append( message );
writer.finish();
}
}catch( Exception e ){
LOGGER.warn("Failed to persist Message [{}]", message );
LOGGER.warn("Exception: ", e );
}
}
}
根据您对这个类的其他操作,同步整个方法可能会更容易
public synchronized final void appendMessage( final String message ){
但这将在ConcurrentPersister实例上同步,而不是在编写器上同步。VanillaChronicle有一个Appender/Tailer的线程本地缓存:
public VanillaAppender createAppender() throws IOException {
WeakReference<VanillaAppender> ref = appenderCache.get();
VanillaAppender appender = null;
if (ref != null)
appender = ref.get();
if (appender == null) {
appender = createAppender0();
appenderCache.set(new WeakReference<VanillaAppender>(appender));
}
return appender;
}
我在某处读到VanillaChronicle的append(字符串消息)
是线程安全的。但是,我是否正确地认为startExcerpt()
+append()
+finish()
的复合动作不是线程安全的
VanillaChronicle可以被并发线程,甚至并发进程使用,只要每个线程使用它自己的appender。writer对象在哪里初始化?对不起,在构造函数中,现在修复了它。+1这允许您在不同的线程中并发写,而不需要自己跟踪appender。
Appender
设计为一次只能由一个线程使用,因此每个线程需要一个线程来避免锁定。伙计们,createAppender()不应该同步以确保创建和返回Appender的过程作为一个原子单元执行吗?
public final void appendMessage( final String message ) {
try {
ExcerptAppender writer = chronicle.createAppender();
writer.startExcerpt( STRING_SIZE_OVERHEAD + message.length() );
writer.append( message );
writer.finish();
} catch( Exception e ) {
LOGGER.warn("Failed to persist Message [{}]", message );
LOGGER.warn("Exception: ", e );
}
}