I recently upgraded the version of my Hibernate to 4.3.4.Final. Based on Contextual Sessions configuration of Hibernate this new version is not based on ThreadLocal anymore.
Access to a single instance of SessionFactory within your aplication is all that is needed.
The following information is all (available) from the Hibernate 4.3 manual chapters 2.2. Contextual sessions and 13. Transactions and Concurrency.
"A SessionFactory is an expensive-to-create, threadsafe object, intended to be shared by all application threads. It is created once, usually on application startup, from a Configuration instance."
"A Session is an inexpensive, non-threadsafe object that should be used once and then discarded for: a single request, a conversation or a single unit of work."
If there is no "unit of work" but just a bunch of (bundled) queries and updates, simply follow the first idiom for the non-managed environment (from chapter 13 mentioned earlier). And unless you can demonstrate this gives performance problems(*), do not try to optimize because that is the root of all evil.
If there is a "unit of work" or "session-per-request", the HibernateUtil from the question can be replaced by using org.hibernate.context.internal.ThreadLocalSessionContext as CurrentSessionContext (see chapter 2.2 mentioned earlier) and following the second idiom for the non-managed environment.
If you use JTA, replace ThreadLocalSessionContext with org.hibernate.context.internal.JTASessionContext and follow the idioms described in Using JTA.
Pay attention to the chapter that discusses the "unit of work": a good architecture for your software depends on a good understanding of what a "business transaction" and "application transaction" means for your application.
(*) Performance problems can be caused by configuration problems, e.g. this question which has related documentation here in the Hibernate manual.