Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.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 VanillaChronicle的线程安全性_Java_Chronicle - Fatal编程技术网

Java 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;

我正在使用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;
    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 );
    }
}