HashMapのソースコードを深く掘り下げます。6.5 hashMapの内部のクラス分割ディズエターHashMapSpliter、KeySpliter、Value Splitert、EntrySplitera
7995 ワード
HashMapのソースコードを深く掘り下げます。6.5 hashMapの内部のクラス分割ディズエターHashMapSpliter、KeySpliter、Value Splitert、EntrySplitera
2018年10月1日18:30:57 成熟した黄小天になろうと努力します。 読書数:251
著作権声明:本文はブロガーのオリジナル文章で、ブロガーの許可なしに転載してはいけません。https://blog.csdn.net/ocp114/article/details/82917933
まず役割を説明します。もとのHashMapにはもうディズマリーがありましたが、なぜこれらのディレクタが必要ですか?愛ですか?責任ですか?(づ。◕‿◕。)づ
ハハハ、李白は存在は合理的だと言いました。
時代の変化に対応するために、並列計算がますます必要になってきました。このローズマリーの誕生も並行反復のために現れました。マルチスレッドの場合は同じHashMapを繰り返してもいいです。しかし、公式はスレッドは一つのローズマリーとしか併用しないと提案しています。
はい、本題に入ります。ここではKeySpliter、Value Splitert、EntrySpliteraは全部Hash MapSpliterに継承されています。ここではKeySpliterとHashMapSpliterのソース解析だけです。他の二つの原理は同じです。いくつかの問題はご覧ください。 1 , 4 5 , , 8 9, 10 11 15 , , , , , 23 , , 30, 31 , 34, , , , 38, 40, , , , , 46 , 49, 50 , 53, , , 59, 60 61, , , 64 65, , , 69 , 71, , , 76 , , , 84 , , , , 89, 90, 91 92, , 94, 95, , , , 100 101, 102 103 104, 105 106, 107, 108 109 110, 111, 112 113 114 115 116 117 118, 119 テストコード 1 , 4 5 , , 8 9, 10 11 15 , , , , , 23 , , 30, 31 出力結果
スレッド2=8スレッド2=9スレッド2=10スレッド2=11スレッド2=12スレッド2=13スレッド2=14スレッド1=16スレッド2=15スレッド3=0スレッド1=17スレッド1=19スレッド1=20スレッド1=21スレッド3=2スレッド3=4スレッド3=5スレッド3=6スレッド3=6スレッド3=7=7
2018年10月1日18:30:57 成熟した黄小天になろうと努力します。 読書数:251
著作権声明:本文はブロガーのオリジナル文章で、ブロガーの許可なしに転載してはいけません。https://blog.csdn.net/ocp114/article/details/82917933
まず役割を説明します。もとのHashMapにはもうディズマリーがありましたが、なぜこれらのディレクタが必要ですか?愛ですか?責任ですか?(づ。◕‿◕。)づ
ハハハ、李白は存在は合理的だと言いました。
時代の変化に対応するために、並列計算がますます必要になってきました。このローズマリーの誕生も並行反復のために現れました。マルチスレッドの場合は同じHashMapを繰り返してもいいです。しかし、公式はスレッドは一つのローズマリーとしか併用しないと提案しています。
はい、本題に入ります。ここではKeySpliter、Value Splitert、EntrySpliteraは全部Hash MapSpliterに継承されています。ここではKeySpliterとHashMapSpliterのソース解析だけです。他の二つの原理は同じです。いくつかの問題はご覧ください。
static class HashMapSpliterator {
// HashMap
final HashMap map;
//
Node current; // current node
//
int index; // current index, modified on advance/split
//
int fence; // one past last index
// ,
int est; // size estimate
// , , HashMap ,
// expectedModCount HashMap modCount , , “ ”
int expectedModCount; // for comodification checks
//
HashMapSpliterator(HashMap m, int origin, int fence, int est, int expectedModCount) {
this.map = m;
this.index = origin;
this.fence = fence;
this.est = est;
this.expectedModCount = expectedModCount;
}
// ? , , 4,
// table ,
final int getFence() { // initialize fence and size on first use
int hi;
// if
if ((hi = fence) < 0) {
HashMap m = map;
est = m.size;
expectedModCount = m.modCount;
Node[] tab = m.table;
hi = fence = (tab == null) ? 0 : tab.length;
}
return hi;
}
//
public final long estimateSize() {
getFence(); // force init
return (long) est;
}
}
static final class KeySpliterator extends HashMapSpliterator implements Spliterator {
KeySpliterator(HashMap m, int origin, int fence, int est, int expectedModCount) {
super(m, origin, fence, est, expectedModCount);
}
//
public KeySpliterator trySplit() {
//
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
// est ~
return (lo >= mid || current != null) ? null :
new KeySpliterator<>(map, lo, index = mid, est >>>= 1, expectedModCount);
}
//
public void forEachRemaining(Consumer super K> action) {
int i, hi, mc;
if (action == null)
throw new NullPointerException();
HashMap m = map;
Node[] tab = m.table;
if ((hi = fence) < 0) {
mc = expectedModCount = m.modCount;
hi = fence = (tab == null) ? 0 : tab.length;
}
else
mc = expectedModCount;
if (tab != null && tab.length >= hi &&
(i = index) >= 0 && (i < (index = hi) || current != null)) {
Node p = current;
current = null;
do {
if (p == null)
p = tab[i++];
else {
action.accept(p.key);
p = p.next;
}
} while (p != null || i < hi);
if (m.modCount != mc)
throw new ConcurrentModificationException();
}
}
// ,
public boolean tryAdvance(Consumer super K> action) {
int hi;
if (action == null)
throw new NullPointerException();
Node[] tab = map.table;
if (tab != null && tab.length >= (hi = getFence()) && index >= 0) {
while (current != null || index < hi) {
if (current == null)
current = tab[index++];
else {
K k = current.key;
current = current.next;
action.accept(k);
if (map.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
}
}
return false;
}
// , , , ,
// ? ? , ~
public int characteristics() {
return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) | Spliterator.DISTINCT;
}
}
static class MyThread implements Runnable {
Spliterator spliterator;
String threadName;
MyThread(Spliterator spliterator, String threadName) {
this.spliterator = spliterator;
this.threadName = threadName;
}
@Override
public void run() {
spliterator.forEachRemaining(s -> {
System.out.println(threadName + "=" + s);
});
}
}
public static void main(String[] args) {
HashMap map = new HashMap<>();
for (int i = 0; i < 23; i++) {
map.put(i, i);
}
Spliterator s1 = map.keySet().spliterator();
Spliterator s2 = s1.trySplit();
Spliterator s3 = s2.trySplit();
Thread t1 = new Thread(new MyThread(s1, " 1"));
Thread t2 = new Thread(new MyThread(s2, " 2"));
Thread t3 = new Thread(new MyThread(s3, " 3"));
t1.start();
t2.start();
t3.start();
}
スレッド2=8スレッド2=9スレッド2=10スレッド2=11スレッド2=12スレッド2=13スレッド2=14スレッド1=16スレッド2=15スレッド3=0スレッド1=17スレッド1=19スレッド1=20スレッド1=21スレッド3=2スレッド3=4スレッド3=5スレッド3=6スレッド3=6スレッド3=7=7