2013-01-09 18 views
19

何回アクセスしたかのカウンタとして機能するBeanを作成する必要があります。 AtomicInteger JEE6 @ApplicationScoped Beanと並行処理

ような
@ApplicationScoped 
class VisitsCounter { 

    private AtomicInteger counter; 

    @PostConstruct 
    public void construct() { 
     counter = new AtomicInteger(0); 
    } 

    public int visited() { 
     return counter.incrementAndGet(); 
    } 
} 

と私は@ApplicationScoped豆を使用したと思ってい

私の質問は:同時に複数の要求を考えるとき、それは大丈夫でしょうか?または、@ConcurrencyManagement@Lockアノテーションで再生する必要がありますか?私はAtomic*がトリックを行うべきだと思うが、私は確信していない。

スレッドセーフなコレクションをフィールドとして使用する場合も同様です。例えば。私が持っていると言う

@ApplicationScoped 
class ValuesHolder { 

    private List<String> values; 

    @PostConstruct 
    public void construct() { 
     values = Collections.synchronizedList(new LinkedList<String>()); 
    } 

    public void insert(String value) { 
     values.add(value); 
    } 

    public String remove(String value) { 
     return values.remove(value); 
    } 
} 

本当にスレッドセーフな操作ですか?

Beanの状態が変更されているときに並行性の注釈とロックを使用する必要がありますが、リストが既にスレッドの安全性を考慮している場合はどうすればよいですか?

+2

実装されているように、私は並行性の問題はありません。 – McDowell

答えて

31

CDIでは、同時実行管理はありません。したがって、@ApplicationScopedは、注入されたオブジェクトのカーディナリティを単に示すだけです(つまり、Beanのインスタンスを1つだけ作成してすべてのアプリケーションで使用するように注入エンジンに指示します)。 EJBでBeanを変換することはなく、並行処理の制約もありません。

したがって、例の操作は本質的にスレッドセーフですが、AtomicIntegerと同期リストのおかげで一般的には同じことは成り立ちません。ことができます。一般的には

  • 手動

  • かにアプリケーションサーバに指示javax.ejb.Singleton注釈を使用し(あなたが行ったように)標準の並行処理プリミティブを通じてアクセスリストを同期並行性を管理する。これにより、EJB内のBeanが変換され、デフォルトでは@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)および@Lock(LockType.WRITE)が適用されます。ところで

@ConcurrencyManagement@LockはシングルトンセッションBeanでのみ使用可能です。

+0

いいです。私は '@Startful' EJBに' @ ApplicationScoped' beanを注入すると何が起こるのか考えていました。問題のあるように思えるのは、EJBの2つのインスタンスから同じデータを変更できるからです。 – dalvarezmartinez1

関連する問題