2013-08-31 43 views
21

Dogクラスが複数のスレッドで共有される1つのインスタンスを持つ場合があります。私はすべてのロギング用SLF4Jを使用する予定:私のloggerインスタンスのスレッドセーフSLF4Jはスレッドセーフですか?

public class Dog { 
    private Logger logger = LoggerFactory.getLogger(Dog.class); 

    // ...etc. 
} 

ですか?なぜ/なぜですか?

答えて

-10

LoggerFactory.getLogger(Class<?>)「キャッシュ」クラスに基づいてLoggerインスタンスを。したがって、LoggerFactory.getLogger(Dog.class)を2回呼び出すと、メモリ内の同じオブジェクトへの参照が2つ取得されます。これは、2つ以上のスレッドがDogをインスタンス化すると、同じ(共有)Dog Loggerインスタンスを取得することを意味します。

したがって、SLF4J APIはではなく、スレッドセーフです。あなたが選んだ拘束にはすべてがあります。一般的なバインディング(log4j、JUL、およびlogback)はスレッドセーフなので、複数のスレッドが同じDog Loggerにアクセスしても、log4j/JUL/logbackロガーバインディングはスレッドセーフであるため、問題はありません。

ポイントで

ケース:あなたはあなた自身のバインディングSLF4Jを作っている場合は、別の方法(ThreadLocalを提供する、など)にすべてのLogger IMPL方法​​、またはアドレススレッドの安全性を確認します。

+15

私はこの答えの推論に欠陥があることを恐れています。異なるスレッドで同じ 'Logger'への2つの参照を取得できるという事実は、SLF4Jをスレッドセーフではありません。私たちが言うことができるのは、SLF4J *のスレッドセーフティはファサードの背後にある実装のスレッドセーフティに依存するということです。 –

+0

a)推論が間違っている(結論が正しいにもかかわらず)正しい答えとしてOPがこれをマークしているのは残念ですが、b)スティーブンCは一日早く正しい正しい言葉の答えを返しました。 – davidbak

33

確かに、誰もと仮定して、Loggerはスレッドセーフであると想定しています。しかし、ファサードの背後にある実装クラスのコード/ javadocsを見ると、が絶対にである必要があります。特定の実装について

(明らかに、これらは、それぞれのコードであることを声明していますをスレッドセーフに設計しました。常にバグがあります。たとえば、現在the Log4j 2 trackerで開いスレッドの安全性のバグのカップルが、それはこれらのバグのように見えるしていませんが、直接あなたのコード例に影響を与える)結論として

+0

ありがとう@Stepen C(+1) - あなたはそれがスレッドセーフであるかどうかを判断する*バインディング*に依存していると言っていますか? SLF4J API自体はどうですか? –

+0

いいえできません。まず、スレッドの安全性は、SLF4Jの一部ではないロガーコードの実装された動作に最終的に依存します! (あなたはSLF4Jがファサードであることを理解していますか?) –

+0

Yep - SLF4Jはファサードであると私は理解しています。多分私はここで間違った質問をしています。私のコード例では、 'Dog'インスタンスが2つ以上のスレッドにまたがっている場合、実行時に使用するSLF4Jバインディングに関係なく、気まぐれな' logger'の動作について心配する必要がありますか、バインディングに関係なく)スレッド間で共有状態を共有することはありませんか? –

関連する問題