私は、以下の非常に簡単コールバックインタフェースとPOJOクラス持っている:ステートレスコールバックをBlockingQueueに入れても安全ですか?
public interface Action{
public void doAction();
}
public class Person{
private String name;
private String address;
//...etc
//GET, SET, toString
}
を私は次のようにそれを使用するつもりです:
public class ActionExecutor{
private static final Logger logger = LogManager.getLogger(ActionExecutor.class);
private final BlockingQueue<Action> blockingQueue = new LinkedBlockingQueue(2000);
public void execute(final Person p){
//modify state of p in some way
blockingQueue.put(new Action(){
public void doAction(){
logger.info("Execution started: " +p.toString);
//do some other job
});
}
}
BlockingQueue
ここではproducer-を実装するために使用されます消費者。
質問:それはBlockingQueue
から行動をとる消費者スレッドが正しいログメッセージを書き込むことが保証されていますか?私。 Person
の正しい状態を観測していますか?しかし、私はそれについて厳密にはわかりません。
プロデューサによる変更とプロデューサによる読み取りの間に注文が発生することはないので、これは保証されません。
いいえ、その保証はありません。 doActionメソッドが呼び出される前に、Person pの状態が変更される可能性があります。 p.toString()の文字列を取得し、その文字列をActionコンストラクタに渡してActionインスタンスのメンバとして格納することができます。 – bhspencer
@bhspencer安全なスレッドセーフなオブジェクトしか公開できません。 –
ここに公開することで何を意味するのか分かりません。私は問題がスレッドの安全性ではなく、状態に関するものだと考えています。アクションをキューに置くと、リファレンスを持つPersonはロックされていない状態になります。したがって、アクションが最終的に実行されたときに、アクションの作成時とは異なる状態になる可能性があります。 Person pはスレッドセーフである可能性がありますが、変更可能な場合はその状態が変更される可能性があります。 – bhspencer