I am not sure I would call it a disadvantage but one must be really careful with cleaning up ThreadLocals properly since whatever data you put in there stays there as long as the thread lives unless it is explicitly removed. This is especially troublesome in an environment where the threads are reused using thread pools so some garbage data maybe attached to thread unless it's cleaned properly.
ThreadLocals are used a lot actually - mainly by framework developers as they allow attaching "context" to user methods without changing method signature. Transaction management in J2EE for example is done with ThreadLocals - the reference to current open transaction is always attached to the thread so that when you work with database you will automatically access it using the currently open transaction. Without ThreadLocal you would need to pass those references as method parameters.
There are many additional examples of such usage. I am not sure what session variables you are referring to but session-like data is often attached to ThreadLocal.
Regarding implementation - I am not sure really. I think I read somewhere that it is implemented inside JVM on fairly low level to make the performance very fast since quite a lot of code uses it today.