I think I understand what you are saying.
Internally thread locals work by generating an internal key for each the thread local variable. In recent implementations (I am looking at Java 11) the keys are generated by a hashing algorithm, and are used in the (custom) map that each thread uses to store the thread-local values.
You are proposing that these maps be replaced by simple arrays of values, and the keys are generated as sequentially increasing integers so that they can be used for subscripting the arrays. I guess you think it would improve performance and/or reduce memory.
The problem is that your idea doesn't scale.
Suppose that an application creates a number of ThreadLocal
instances. Now suppose that a thread sets the value of the i
th ThreadLocal
for some random i
.
In the current implementation, an entry is created in the thread's hash table. This takes a constant amount of space.
In your proposed implementation, the thread's array now needs to have at least i
slots, where i
is the key. (Java arrays are not sparse!). If it doesn't exist yet, it must be created with length i
. If it does exist, it may need to be reallocated with length i
.
When the number of ThreadLocal
instances is large enough, and they are set randomly, and only a few are set for any given thread, then the memory used by your array-based representation will be greater than for the current hash table representation.
Then, consider what happens when a ThreadLocal
is garbage collected.
In the current hash table implementation, each map entry is (extends) a WeakReference
whose ref
refers to a ThreadLocal
. When a given ThreadLocal
instance is garbage collected, all entries in all threads' maps for that ThreadLocal
will have their ref
field nulled. The map's implementation recognizes any such entries as "stale", and when it encounters a stale entry, it expunges it from the table.
In your proposed implementation, there is no WeakReference
to break. Even if that could be worked around, it is difficult to see how the arrays could be compacted.
Now, the Sun / Oracle engineers who worked on the Java implementation are all smart people. And the particular engineers who implemented and maintained ThreadLocal
over the years probably looked for ways to optimize it. And they may well have considered using arrays at some point. But I imagine that they would have considered all of the pros and cons1 ... before deciding on the current approach of using a hash table per thread.
It is also worth understanding the background for the current implementation. There are clues in this (fixed) bug report against the JDK 1.4 codebase: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4414045
1 - These may well have included other issues than the above ones ...
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…