Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
93 views
in Technique[技术] by (71.8m points)

java - Why use a map in Thread to store ThreadLocal objects?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 ith 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 ...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...