I have a customer who's stuck in an EJB 3.0 environment. No @Singleton, no bean-managed concurrency :-(
Considering thread management and synchronization is forbidden by the ejb specification, how to implement a cache? In essence, I want an non-synchronized object cache for some costly operations.
I doubt whether I understood your question clearly or not! Following example is based on
weblogic
andeclipselink
.If you are using eclipselink JPA for your EJB, you can use cache for your every entities separately like this:
If you want, you can enable caching for all the entities from the persistence.xml file also. This will be like this inside the property field(oracle doc's link):
Cache type can be different like Soft, Hard, Weak, Full, etc. Each of them is having their own meaning. You can find more about this cache type from here.
The restriction of using static field and synchronization is stated in EJB 3.0 spec chapter 21.1.2. It also explains why.
If you implement a cache by singleton POJO, you may have the risk that actually there are multiple cache instances in each JVM if EJB container distributed EJB instances across multiple JVMs, for instance, in a cluster environment.
So it depends,
If it doesn't work for you, probably you should think about caching data outside of EJB container, e.g. put in Redis or Hazelcast.
Are even volatile variables forbidden in an EJB container? A volatile int variable provides some guarantees that are useful for multithreaded code. If a thread sees the change of a volatile variable, it is safe to assume that it sees everything that happened before.
Another idea would be a @Stateful bean that is instantiated only once (calls will be serialized by the container). I'm not sure about the implementation details, though.
Well, I think that ConcurrentSkipListMap could be the solution: no synchronization but still thread-safe.