2017-08-18 12 views
-1

StringBufferまたはsynchronizedメソッドですか?私は次のコードしている

public class MyLogger { 
    private StringBuilder logger = new StringBuilder(); 

    public void log(String message, String user) { 
     logger.append(message); 
     logger.append(user); 
    } 
} 

プログラマは単一MyLoggerオブジェクトが マルチスレッドシステムに正常に動作することを保証しなければなりません。 このコードをスレッドセーフにするにはどのように変更する必要がありますか?

A.ログメソッドを同期

B. StringBuffer

StringBuilderを交換する最良の方法を教えてください。

+0

だから、これはロガーに蓄積し、ポイントは何ですか? –

+0

私は、両方の文字列のコピーを保持する 'LogEntry'クラスのインスタンスと、Blocking Queueの終わりで待機するロガースレッドへのコマンドを使用することをお勧めします。 –

答えて

3

StringBufferは、二つの情報が常に送信されることを保証するだけでは十分ではないグループ化:

logger.append(message); 
    logger.append(user); 

それはそれだけでappend()が同時の方法で起動されませんので、あなたがリスク破るないことを保証StringBufferオブジェクトの状態です。
あなたは確かにlog()呼び出し中にインターリーブ二つのスレッドを持っており、これらの呼び出しを得ることができます:

スレッド1:logger.append(メッセージ);

スレッド2:logger.append(メッセージ);

スレッド1:logger.append(user);

スレッド2:logger.append(user);

これはとても良いです。

public synchronized void log(String message, String user) { 
     logger.append(message); 
     logger.append(user); 
    } 

ます。また、プライベートloggerオブジェクトの同期化を行うことができます。
クラスのクライアントがクラスの外部にロックすることを許可しないという利点があります。あなたが選択した場合にStringBufferを使用するため

+2

メソッドシグネチャで 'synchronized'を使用するよりも、プライベートオブジェクトでの同期がより良い選択であることに言及したいことがあります。 –

+1

@Alvin Thompsonは助言しています。私はそれを加えた。 – davidxxx

+0

素敵な説明のために@davidxxxに感謝します。私の理解が間違っているかどうか教えてください:スレッド1はlogger.append(メッセージ)を実行する機会を得ました。 T1はSBオブジェクトにロックを持ち、メソッド実行が完了するとSB上のロックを解除しますか? T2はlogger.append(message)を実行できます。問題が発生する可能性がありますか?これはあなたが描こうとしていたものですか? –

0

使用A、あなたは混乱のログができます。これは、StringBufferので起こる可能性が (間違ったログを生成します):

logger.append(message); < Thread A 
logger.append(message); < Thread B 
logger.append(user); < Thread A 
logger.append(user); < Thread B 
関連する問題