我想知道为什么var tracker: any[] = [];
方法通过本地分配的变量对元素数组执行操作,而不是直接访问类成员。它是否与同步有关(在方法调用之间保持元素数组一致?)
例如:java.util.Hashtable
在
Entry<?,?> tab[] = table;
或
private void addEntry(int hash, K key, V value, int index) {
420 modCount++;
421
422 Entry<?,?> tab[] = table;
423 if (count >= threshold) {
424 // Rehash the table if the threshold is exceeded
425 rehash();
426
427 tab = table;
428 hash = key.hashCode();
429 index = (hash & 0x7FFFFFFF) % tab.length;
430 }
答案 0 :(得分:2)
我感觉很糟糕,只留下评论,这个问题值得一个正确的答案,所以这里是一个快速尝试重新发布(ha)这些评论。
Hashtable
已同步(所有公开方法均为synchronized
,或返回同步集合(keySet()
,entrySet()
,values()
)) thread safe (某些规则和限制可能适用) rehash()
方法是protected
:可以从子类调用它。 synchronized
,因此子类的实例可以同时调用rehash()
另一个需要访问table
的方法。
因此,为了避免table
上的竞争条件,这些方法会保存对数组的引用的本地副本,然后可以安全地使用该本地数组:如果调用rehash()
,它将构建一个新数组不会干扰处理旧数组的其他线程。来自JDK 1.0.2的版本就像那样(找到它here,Windows .exe
是自我提取的zip文件,所以unzip
处理那个,在那里你找到src.zip
- 有趣的是看到里面有3个类的Hashtable.java
,没有像1.1中引入的内部类。)
这种设计鼓励继承Hashtable
从其功能中受益,但应该优先考虑组合。我找到了bug entry特定于Hashtable
的子类(虽然不是关于线程安全性),其中Josh Bloch说:
使用委托而不是子类化可以避免这种问题。
在评论中引用@pvg,获得一个很好的总结:
一个稍微宽泛的答案是,这基本上是一个90年代早期的设计,它的寿命很长而且显示出来。它是一个通过子类同时尝试既线程安全又可扩展的类,类库在以后的设计迭代中避免使用。
答案 1 :(得分:-1)
这非常简单 - rehash()
将重写table
字段,因此将它们保存到临时变量以便以后访问。