Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / fairness of ConcurentHashMap / 19 сообщений из 19, страница 1 из 1
10.03.2017, 18:03
    #39417144
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
1. Поток 1 вставляет данные в сегмент_1(это операция занимает какое-то время)
2. Поток 2 хочет прочитать данные из сегмента_1 в момент времени 2(когда поток 1 один ещё не завершил put)
3. Поток 3 пытается вставить данные в сегмент_1 в момент времени 3(когда поток 1 один ещё не завершил put)


Кто победит? поток 2 или поток 3 ?



и похожий вопрос про ReentrantReadWriteLock

Пока сидим в read локе прилетело 2 запроса на read и write. Кто победит?

1. Не fair
2. Fair.
...
Рейтинг: 0 / 0
13.03.2017, 11:01
    #39417908
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
По поводу мапы выяснил, что там мутабельная и не мутабельная операция на одном сегменте может исполняться в параллель. Это сюрприз.

А по поводу ReadWriteLock - неясно
...
Рейтинг: 0 / 0
13.03.2017, 11:20
    #39417918
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
по поводу ReentrantReadWriteLock переформулирую

Если во время чтения в не-fair моде прилетело ещё 2 запроса. Один из которых на чтение, а другой на запись, то будет ли преимущество у того, который на чтение по той причине, что чтение уже идёт ?
...
Рейтинг: 0 / 0
13.03.2017, 11:49
    #39417943
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questioner,

стесняюсь спросить, а вам в лом посмотреть исходники сдк?
...
Рейтинг: 0 / 0
13.03.2017, 14:44
    #39418143
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
А мне практический смысл вопроса не очень понятен. Если практически становятся такие вещи важны - это же какая конкуренция должна быть? Честно говоря, мне такое даже не представить. Точнее не представить, как при такой конкуренции система работает, а не "стоит колом". AFAIK Если конкуренция настолько зашкаливает, хорошо бы еще убедится, что дело именно в Java-коде, а например не в планировщике ОС и/или параметрах java машины.

Ну и опять таки, существует 100500 альтернативных реализаций конкурентных коллекций. Выбирай не хочу. На Oracle/Sun реализации все клином не сошлось. Да и выбор в стандартной Java не сильно уж и богатый (точнее выбора вообще нет)

IMHO & AFAIK
...
Рейтинг: 0 / 0
13.03.2017, 15:56
    #39418208
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
twr143questioner,

стесняюсь спросить, а вам в лом посмотреть исходники сдк?
Они не настолько очевидно написаны. Но если Вы в состоянии, то я буду рад услышать ваше мнение.
...
Рейтинг: 0 / 0
13.03.2017, 15:58
    #39418210
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
Leonid KudryavtsevА мне практический смысл вопроса не очень понятен. Если практически становятся такие вещи важны - это же какая конкуренция должна быть? Честно говоря, мне такое даже не представить. Точнее не представить, как при такой конкуренции система работает, а не "стоит колом". AFAIK Если конкуренция настолько зашкаливает, хорошо бы еще убедится, что дело именно в Java-коде, а например не в планировщике ОС и/или параметрах java машины.

Ну и опять таки, существует 100500 альтернативных реализаций конкурентных коллекций. Выбирай не хочу. На Oracle/Sun реализации все клином не сошлось. Да и выбор в стандартной Java не сильно уж и богатый (точнее выбора вообще нет)

IMHO & AFAIK
На собеседовании спросили.

В целом неплохо иметь понимание как работает инструмент с которым приходится работать. Ну и выбор инструмента зависит от понимания того как он работает.
...
Рейтинг: 0 / 0
13.03.2017, 19:15
    #39418376
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questioner,

ConcurrentHashMap (8):
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
    public V put(K key, V value) {
        return putVal(key, value, false);
    }

    /** Implementation for put and putIfAbsent */
    final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            else {
                V oldVal = null;
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node<K,V> e = f;; ++binCount) {
                                K ek;
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node<K,V> pred = e;
                                if ((e = e.next) == null) {
                                    pred.next = new Node<K,V>(hash, key,
                                                              value, null);
                                    break;
                                }
                            }
                        }
                        else if (f instanceof TreeBin) {
                            Node<K,V> p;
                            binCount = 2;
                            if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                    }
                }
                if (binCount != 0) {
                    if (binCount >= TREEIFY_THRESHOLD)
                        treeifyBin(tab, i);
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            }
        }
        addCount(1L, binCount);
        return null;
    }



в методе putVal синхронизация идёт по первой ноде сегмента, синхронизация интринсик, автоматически unfair.
get:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
    public V get(Object key) {
        Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
        int h = spread(key.hashCode());
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (e = tabAt(tab, (n - 1) & h)) != null) {
            if ((eh = e.hash) == h) {
                if ((ek = e.key) == key || (ek != null && key.equals(ek)))
                    return e.val;
            }
            else if (eh < 0)
                return (p = e.find(h, key)) != null ? p.val : null;
            while ((e = e.next) != null) {
                if (e.hash == h &&
                    ((ek = e.key) == key || (ek != null && key.equals(ek))))
                    return e.val;
            }
        }
        return null;
    }


Здесь блокировка отсутствует в принципе. Вывод: put и get независимы, операции put в каждый сегмент последовательны.
...
Рейтинг: 0 / 0
13.03.2017, 20:11
    #39418417
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questioner,

ReadWriteLock.
ReadLock - попытка захвата: первый пункт в комменте говорит что read ждёт write, первый if это имплементит.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
protected final int tryAcquireShared(int unused) {
            /*
             * Walkthrough:
             * 1. If write lock held by another thread, fail.
             * 2. Otherwise, this thread is eligible for
             *    lock wrt state, so ask if it should block
             *    because of queue policy. If not, try
             *    to grant by CASing state and updating count.
             *    Note that step does not check for reentrant
             *    acquires, which is postponed to full version
             *    to avoid having to check hold count in
             *    the more typical non-reentrant case.
             * 3. If step 2 fails either because thread
             *    apparently not eligible or CAS fails or count
             *    saturated, chain to version with full retry loop.
             */
            Thread current = Thread.currentThread();
            int c = getState();
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current)
                return -1;
            int r = sharedCount(c);
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                if (r == 0) {
                    firstReader = current;
                    firstReaderHoldCount = 1;
                } else if (firstReader == current) {
                    firstReaderHoldCount++;
                } else {
                    HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != getThreadId(current))
                        cachedHoldCounter = rh = readHolds.get();
                    else if (rh.count == 0)
                        readHolds.set(rh);
                    rh.count++;
                }
                return 1;
            }
            return fullTryAcquireShared(current);
        }



WriteLock: попытка захвата: первый коммент говорит что write ждёт все залоченные риды и залоченный write.
Код, следующий за // (Note: if c != 0 and w == 0 then shared count != 0) это имплементит
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
protected final boolean tryAcquire(int acquires) {
            /*
             * Walkthrough:
             * 1. If read count nonzero or write count nonzero
             *    and owner is a different thread, fail.
             * 2. If count would saturate, fail. (This can only
             *    happen if count is already nonzero.)
             * 3. Otherwise, this thread is eligible for lock if
             *    it is either a reentrant acquire or
             *    queue policy allows it. If so, update state
             *    and set owner.
             */
            Thread current = Thread.currentThread();
            int c = getState();
            int w = exclusiveCount(c);
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // Reentrant acquire
                setState(c + acquires);
                return true;
            }
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            setExclusiveOwnerThread(current);
            return true;
        }
...
Рейтинг: 0 / 0
13.03.2017, 23:41
    #39418519
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
twr143ReadWriteLock.
ReadLock - попытка захвата: первый пункт в комменте говорит что read ждёт write, первый if это имплементит.

автор1. If write lock held by another thread, fail.
Только если этот writeLock уже захвачен. Про конкуренцию за лок ничего не написано


twr143WriteLock: попытка захвата: первый коммент говорит что write ждёт все залоченные риды и залоченный write.
Код, следующий за // (Note: if c != 0 and w == 0 then shared count != 0) это имплементит


авторIf read count nonzero or write count nonzero and owner is a different thread, fail.

Аналогично.


Меня беспокоит вариант, что если read lock никогда не отпускается, то это значит, что writeLock не имеет даже теоретических шансов захватиться
...
Рейтинг: 0 / 0
14.03.2017, 07:44
    #39418565
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questioner,

в методе readerShouldBlock , вызывающемся из tryAcquireShared и writerShouldBlock из tryAcquire описаны стратегии дополнительной фильтрации для FairSync и NonfairSync.
...
Рейтинг: 0 / 0
14.03.2017, 10:53
    #39418649
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
twr143questioner,

в методе readerShouldBlock , вызывающемся из tryAcquireShared и writerShouldBlock из tryAcquire описаны стратегии дополнительной фильтрации для FairSync и NonfairSync.

Ну как-то там не много написано.

Код: java
1.
2.
3.
4.
5.
6.
7.
  final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }
...
Рейтинг: 0 / 0
14.03.2017, 12:22
    #39418773
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questionertwr143questioner,

в методе readerShouldBlock , вызывающемся из tryAcquireShared и writerShouldBlock из tryAcquire описаны стратегии дополнительной фильтрации для FairSync и NonfairSync.

Ну как-то там не много написано.

Код: java
1.
2.
3.
4.
5.
6.
7.
  final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }



сий код вам говорит, что ридер в режиме unfair c радостью пропустит первый поток в очереди, если он writer. У ноды head потока нет, в чём вы можете убедиться, изучив метод setHead. Поэтому первый поток в очереди хранит нода h.next
...
Рейтинг: 0 / 0
14.03.2017, 16:44
    #39419096
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
twr143questionerпропущено...


Ну как-то там не много написано.

Код: java
1.
2.
3.
4.
5.
6.
7.
  final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }



сий код вам говорит, что ридер в режиме unfair c радостью пропустит первый поток в очереди, если он writer. У ноды head потока нет, в чём вы можете убедиться, изучив метод setHead. Поэтому первый поток в очереди хранит нода h.next

А как вы по этому отрывку это поняли? Это список чего хоть?

Вот в JCIP нашёл:

авторInternally, AQS maintains a queue of waiting threads, keeping track of whether a thread has requested exclusive or
shared access. In ReentrantRead-WriteLock, when the lock becomes available, if the thread at the head of the queue
was looking for write access it will get it, and if the thread at the head of the queue was looking for read access, all
queued threads up to the first writer will get it.[15]
[15] This mechanism does not permit the choice of a readerͲpreference or writerͲpreference policy, as some readͲwrite lock implementations do.
For that, either the AQS wait queue would need to be something other than a FIFO queue, or two queues would be needed. However, such a strict
ordering policy is rarely needed in practice; if the nonfair version of ReentrantReadWriteLock does not offer acceptable liveness, the fair
version usually provides satisfactory ordering and guarantees nonstarvation of readers and writers

То есть получается, что ридеры не могу обгонять врайтеров и, видимо, наоборот, тоже.

Но это как-то уж сильно напоминает fair policy. Или разница fair мода только в том, что внутри группы ридеров/врайтеров порядок гарантированный.
...
Рейтинг: 0 / 0
14.03.2017, 16:45
    #39419098
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
twr143,

авторсий код вам говорит, что ридер в режиме unfair c радостью пропустит первый поток в очереди, если он writer.

Откуда вообще очередь в unfair mode ?
...
Рейтинг: 0 / 0
14.03.2017, 17:01
    #39419109
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
fair:
JDK * <dt><b><i>Fair mode</i></b>
* <dd>When constructed as fair, threads contend for entry using an
* approximately arrival-order policy. When the currently held lock
* is released, either the longest-waiting single writer thread will
* be assigned the write lock, or if there is a group of reader threads
* waiting longer than all waiting writer threads, that group will be
* assigned the read lock.
*
* <p>A thread that tries to acquire a fair read lock (non-reentrantly)
* will block if either the write lock is held, or there is a waiting
* writer thread. The thread will not acquire the read lock until
* after the oldest currently waiting writer thread has acquired and
* released the write lock. Of course, if a waiting writer abandons
* its wait, leaving one or more reader threads as the longest waiters
* in the queue with the write lock free, then those readers will be
* assigned the read lock.
*

В первом потоке пишут, что может захватить как writer, так и группа reader-ов, которая ждёт дольше самого древнего write-а, а во втором, что read не сможет захватить лок до тех пор пока есть write который ждёт.
...
Рейтинг: 0 / 0
14.03.2017, 17:01
    #39419112
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
авторВ первом потоке
абзаце*
...
Рейтинг: 0 / 0
14.03.2017, 17:17
    #39419129
twr143
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
questionerfair:
JDK * <dt><b><i>Fair mode</i></b>
* <dd>When constructed as fair, threads contend for entry using an
* approximately arrival-order policy. When the currently held lock
* is released, either the longest-waiting single writer thread will
* be assigned the write lock, or if there is a group of reader threads
* waiting longer than all waiting writer threads, that group will be
* assigned the read lock.
*
* <p>A thread that tries to acquire a fair read lock (non-reentrantly)
* will block if either the write lock is held, or there is a waiting
* writer thread. The thread will not acquire the read lock until
* after the oldest currently waiting writer thread has acquired and
* released the write lock. Of course, if a waiting writer abandons
* its wait, leaving one or more reader threads as the longest waiters
* in the queue with the write lock free, then those readers will be
* assigned the read lock.
*

В первом потоке пишут, что может захватить как writer, так и группа reader-ов, которая ждёт дольше самого древнего write-а, а во втором, что read не сможет захватить лок до тех пор пока есть write который ждёт.


Чтобы не задавать такие вопросы я и вставил вам код tryAcquireShared и tryAcquirу. В первой части этих методов реквест фильтруется на основе уже фактически захваченных локов. Во второй части (writerShouldBlock() и readShouldBlock()) локи свободны и возможная фильтрация идёт на основе порядка других потоков в очереди ожидания! Ваш вопрос про первую часть, а я вам уже объясняю вторую ! Не смешивайте апельсины и яблоки!
...
Рейтинг: 0 / 0
14.03.2017, 20:24
    #39419293
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
fairness of ConcurentHashMap
Offtopic

questionerВ целом неплохо иметь понимание как работает инструмент с которым приходится работать.

Хорошо понимать из какого корпуса сделан микроскоп, что бы знать, через сколько ударов по гвоздю он сломается.

А перед пользованием молотком, хорошо бы прочитать учебник по сопротивлению материалов.
questionerНу и выбор инструмента зависит от понимания того как он работает.

Выбор инструмента зависит от ЗАДАЧИ которую приходится решать.

Понимание того, как он работает - обычно требуется тогда, когда инструмент сломался и его приходится чинить.

Более часто встречающаяся ситуация, когда реклама (документация и т.д.) для инструментов почти полностью НЕ соответствует действительности. Тогда хорошо бы хоть примерно понимать из чего оно сделано. Иначе результат может быть как от патентованной краски, которой Киса Воробьянинов голову покрасил (12 стульев).

IMHO & AFAIK

questionerНа собеседовании спросили.

Мне кажется, что если кто-то бы напрягся и написал сборник "вопросы на собеседовании", то он имел бы успех не меньший, чем всемирно известные "армейские маразмы".

questionerЕсли во время ....
IMHO ответ на данный вопрос находится... в документации

В документации этого нет? Значит, как бы класс реально не работал, это undocumented поведение и закладываться на него при написании реальной системы НЕЛЬЗЯ.

В целом, можно повторить слова, которым более 2000 лет:

"От многих знаний, много печалей. Поэтому тот, кто приумножает знания, приумножает скорбь"

Пожалейте этот мир. Не делайте его еще хуже.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / fairness of ConcurentHashMap / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]