Pieter’s day 4 at JavaOne 2009 summary
Friday, June 05
Well guys, last day of JavaOne 2009 today. I first went to the morning general session, also known as the “toy show” and presented by James Gosling.It was a cool session, with all kinds of cool uses of the Java language. Some examples: gaming (RuneScape), SIM cards, robots, … But the coolest thing I’ve seen is without a doubt the automatic driving of a Audi TT at 160 km/h over a rally track (without a pilot!), all powered by Java technology.
A Java™ Persistence API Mapping Magical Mystery Tour 10:50 - 11:50
By Mike Keith (Oracle)
Well I’m back in room 134, also known as “the freezer”. Jeezes it’s cold in here, I guess it’s to make sure people don’t fall asleep during the session
Anyway, back for another presentation about JPA (how to make the most out of JPA mappings), I hope I see some interesting stuff today.
This session starts off with an overview of object-relational mapping, I’m not going to detail on that because you can find that in my previous posts about the JPA 2.0 spec.
Generating a DDL based on your JPA mappings is basically a bad idea.It will work, but it won’t be optimized for performance.Don’t ignore the database and see everything from a Java perspective!
We see an example of a Map JPA mapping where the key of the map is an entity, this new in JPA 2.0.
Use @AttributeOverride to use Embeddables in multiple objects.
This session turns out to be an introduction to JPA, very basic and for people who haven’t worked with JPA yet. It’s a shame because I was expecting some advanced, in depth stuff from this session…Based on the level of the 3 JPA sessions I attended this conference, I get the feeling they’re still a lot of people out there who are not familiar with JPA yet.
Robust and Scalable Concurrent Programming: Lessons from the Trenches 12:10 - 13:10
Writing safe and concurrent code is hard
- Thread safety don’t fully understand the Java Memory Model
- Thread safety concerns are not easily isolated
Writing safe and scalable code is even harder! Tune only if it is shown to be a real hotspot
Key patterns:
Lazy initialization initialize only when first used
example: non thread safe singleton
adding synchronized keyword: now thread safe but a potential lock contention: can pose serious scalability issuer if it is in critical path
- Eager initialization is the way to go! No reason to lazy init (dates from times when we thought allocations were expensive and timeconsuming);Static initialization takes care of thread safety, and is also lazy
For singletons you gain nothing by using an explicit lazy init.
–> private static final Singleton instance = new Singleton()
Lazy init makes sense:
- if instantiation is truly expensive and it has a chancde of not being needed
- if you want to retry if it fails first time
- if you wanto unload and reload the object
- to reduce confusion if there was an exception during eager initialization: ExceptioninInInitializerError: NoClassDefFoundError for subsequent calls (if original error has long gone, this can be very confusing!)
For 95% of the cases eager init is the case
Lazy init pattern: holder pattern (for non-singletons) –> takes advantage of static initializaton, double-checked locking pattern,
- Maps & Compound operation: maps are common way of storing data.
Don’t play with fire: never modify an unsynchronized collection concurrently.ConcurrentModificationException is not a guarantee –> my end up in infinite loop, wrong result without any errors; data corruption, etc
Bad fix: synhronize the map (Collections.synchronizedMap): individual operations (get and put are threadsafe, other methods not eg increment)
Fix: synchronize the operations (sync mutators + accessors). Correct fix but does it scale? May also become a source of lock contention
Good fix: ConcurrentHashMap comes to the rescue (scales signif better than a synchronized Hashmap under concurrency)
- full reader concurrency
- some writer concurreny with finer grained locking
ConcurrentHashMap interface supports additional thread safe methods ; eg putIfAbsent()
Good fix: ConcurrentHashMap with atomic variables (AtomicInteger)
Use API from java.util.concurrent
- Other people’s classes
- unsafe classes (some JDK classes are no thread safe: DateFormat, MessageDigest, Charsetencoder/CharsetDecoder
- do not assume thread safety on others’ classes.Even javadoc may not give full disclosure.
Bad Fix: synchronize, this works but can result in lock contention
Fix: instantiate every time or use ThreadLocal if your concerned about allocation cost
Way to determine contended locks:
- lock analyzers, CPU profiling (oprofile, cprofile)
- …
Proactive:
- regular training and documentation
- static code analysis
- runtime code analysis
- ongoing performance monitoring and measurements
Best practice: setup lab to put applications under microscope
The Art of (Java™ Technology) Benchmarking 14:50 - 15:50
I was hoping to get some advice on how to write good benchmark tests, but saw an overview of benchmarking specs, which I had never heard of before.So kinda disappointment here…This session was for JVM engineers.
You must be logged in to post a comment.