Why should Java ThreadLocal variables be static

Because if it were an instance level field, then it would actually be "Per Thread - Per Instance", not just a guaranteed "Per Thread." That isn't normally the semantic you're looking for.

Usually it's holding something like objects that are scoped to a User Conversation, Web Request, etc. You don't want them also sub-scoped to the instance of the class.
One web request => one Persistence session.
Not one web request => one persistence session per object.


Either make it static or if you are trying to avoid any static fields in your class - make the class itself a singleton and then you can safely use the an instance level ThreadLocal as long as you have that singleton available globally.


It doesn't have to be. The important thing is that it should be a singleton.


The reason is that the variables are accessed via a pointer associated with the thread. They act like global variables with thread scope, hence static is the closest fit. This is the way that you get thread local state in things like pthreads so this might just be an accident of history and implementation.