Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

java - JEE6 @ApplicationScoped bean and concurrency

I need to write a bean that would act as a counter of how many times it was accessed.

I'm thinking of using @ApplicationScoped bean with AtomicInteger like that

@ApplicationScoped
class VisitsCounter {

    private AtomicInteger counter;

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

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

My question is: is it ok when considering multiple requests at the same time? Or do i need to play with @ConcurrencyManagement and @Lock annotations? I suppose that Atomic* should do the trick but I'm not sure.

Also does the same applies when I have thread safe collections as a fields? E.g. say I have

@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);
    }
}

are the operations really thread-safe?

It is said that concurrency annotations and locks should be used when there is modification of state of the bean, but what if my list already takes care of thread safety?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In CDI you don't have concurrency management, so @ApplicationScoped simply states the cardinality of the injected object (i.e. instructs the injection engine to create only one instance of your bean and use it across all the application). It does not transform your bean in an EJB, and does not enforce any concurrency constraint.

So, while the operations in the examples are inherently thread safe, thanks to the AtomicInteger and the synchronized list, the same is not true in general.

In the general you can:

  • manually synchronize the list accesses through the standard concurrency primitives (as you have done)

  • or use the javax.ejb.Singleton annotation, which instructs the application server to manage concurrency. This transforms your bean in an EJB and by default enforces @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) and @Lock(LockType.WRITE).

By the way, @ConcurrencyManagement and @Lock are only available on singleton session beans.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...