adam bien's blog

@Singleton - The Perfect Cache Facade 📎

@Singleton in the default configuration is the perfect bottleneck. Only one thread a time can access a @Singleton instance.
The annotation @ConcurrencyManagement(ConcurrencyManagementType.BEAN) deactivates this limitation and makes a Singleton instance accessible from multiple threads:
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
import javax.ejb.ConcurrencyManagement;
import java.util.concurrent.ConcurrentHashMap;
import javax.ejb.ConcurrencyManagementType;

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Hits {

    private ConcurrentHashMap hits = null;
	
	@PostConstruct
    public void initialize() {
        this.hits = new ConcurrentHashMap();
	}
//cache accessors omitted
}

A java.util.concurrent.ConcurrentHashMap can be accessed by multiple threads consistently without any locking or synchronization required.

[See also page 67, section "Singletons Are Not Completely Dead" in Real World Java EE Night Hacks--Dissecting the Business Tier and the classes Hits and HitsCache in X-ray. X-ray uses a ConcurrentHashMap for deferred writes and is able to handle 1.400 writes/transactions a second - see section "Finding Bugs with Stress Tests" (page 152)]