24

アクセス回数のカウンターとして機能する Bean を作成する必要があります。

私は@ApplicationScopedビーンをAtomicIntegerそのように使うことを考えています

@ApplicationScoped
class VisitsCounter {

    private AtomicInteger counter;

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

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

私の質問は、複数のリクエストを同時に検討しても大丈夫ですか? @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 の状態が変更された場合は、同時実行アノテーションとロックを使用する必要があると言われていますが、リストが既にスレッド セーフを処理しているとしたらどうでしょうか。

4

1 に答える 1

41

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

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

一般的に、次のことができます。

  • 標準の同時実行プリミティブを介してリストアクセスを手動で同期します(行ったように)

  • またはjavax.ejb.Singleton、アプリケーション サーバーに同時実行性を管理するよう指示するアノテーションを使用します。これにより、Bean が EJB に変換され、デフォルトで and が適用され@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)ます@Lock(LockType.WRITE)

ちなみに、シングルトン セッション Bean@ConcurrencyManagement@Lockのみ使用できます。

于 2013-01-10T12:44:26.053 に答える