Я читаю исходный код ConcurrentHashMap
в JDK8, обратите внимание, что TreeBin
использует блокировку «чтение-запись» для предотвращения одновременного чтения и записи.
Потоки чтения будут проходить через TreeNodes, если нет потока параллельной записи, пытающегося изменить древовидную структуру. Когда операция 'find' завершена, чтение ветки может:
(1) 'CAS' lockState
и «отменить парковку» потока официанта (писателя), если он существует.
Ниже приведен метод 'find ()' в исходном коде.
final Node<K,V> find(int h, Object k) {
if (k != null) {
for (Node<K,V> e = first; e != null; ) {
int s; K ek;
if (((s = lockState) & (WAITER|WRITER)) != 0) {
if (e.hash == h &&
((ek = e.key) == k || (ek != null && k.equals(ek))))
return e;
e = e.next;
}
else if (U.compareAndSwapInt(this, LOCKSTATE, s,
s + READER)) {
TreeNode<K,V> r, p;
try {
p = ((r = root) == null ? null :
r.findTreeNode(h, k, null));
} finally {
Thread w;
// (1)if no more readers, try to unpark the waiter if it exists
if (U.getAndAddInt(this, LOCKSTATE, -READER) ==
(READER|WAITER) && (w = waiter) != null)
LockSupport.unpark(w);
}
return p;
}
}
}
return null;
}
с другой стороны, автор может:
вот код автора:
private final void contendedLock() {
boolean waiting = false;
for (int s;;) {
if (((s = lockState) & ~WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
if (waiting)
waiter = null;
return;
}
}
else if ((s & WAITER) == 0) {
if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
waiting = true;
waiter = Thread.currentThread();
}
}
else if (waiting)
LockSupport.park(this);
}
}
ЗДЕСЬ МОЙ СБОРНИК:
Если указанные выше четыре операции выполняются в этом порядке (2) (1) (3) (4), операция (1) ничего не будет снимать с парковки, поскольку в этот момент «официант» был нулевым.
Тогда официант навсегда припаркуется, и никто не сможет его разгрузить.
Все последующие записи будут заблокированы на внутренней блокировке, удерживаемой «припаркованным» потоком.
ЭТО ШАНС ЗАКРЫТИЯ?
Я действительно смущен этим. Я думаю, что, возможно, я что-то упустил в исходном коде. Нужна ваша помощь, если вы с ней знакомы.