The most common usage I know of is to attach security context (user identification, credentials, groups, etc...) to a thread servicing an HTTP request. In that way any of the "downstream" called methods can check the permissions of the original caller.
With a ThreadLocal, you can create one copy of some value per thread - so if you have multiple threads that access the value, there will be a separate copy for each thread.
One of the examples that this is sometimes used with is with SimpleDateFormat. Class SimpleDateFormat is not thread-safe; you must not try to use the same SimpleDateFormat object from different threads at the same time, because then you'll get strange results and maybe even exceptions. Look at this: