java.util.concurrent обзор кода - PullRequest
       3

java.util.concurrent обзор кода

4 голосов
/ 06 февраля 2011

Я изучаю java.util.concurrent библиотеку и нахожу множество бесконечных циклов в исходном коде, как этот

//java.util.concurrent.atomic.AtomicInteger by Doug Lea
public final int getAndSet(int newValue) {
    for (;;) {
        int current = get();
        if (compareAndSet(current, newValue))
            return current;
    }
}

Интересно, в каких случаях фактическое значение не может быть равным ожидаемому значению (в этом случае compareAndSet возвращает false)?

Ответы [ 4 ]

10 голосов
/ 06 февраля 2011

Многие современные процессоры имеют compareAndSet() отображение на атомарную аппаратную работу. Это означает, что он потокобезопасен и не требует синхронизации (что является сравнительно дорогой операцией по сравнению). Тем не менее, только compareAndSet() само по себе является атомарным, так что для getAndSet() (т.е. установите переменную на заданное значение и верните значение, которое она имела в то время, без возможности ее установки на другое значение в между) код использует хитрость: сначала он получает значение, затем пытается compareAndSet() с только что полученным значением и новым значением. Если это не удается, переменная была обработана другим потоком между ними, и код пытается снова.

Это быстрее, чем использование синхронизации, если compareAndSet() редко дает сбой, то есть, если в переменную одновременно записывается не слишком много потоков. В крайнем случае, когда много потоков пишут в переменную все время, синхронизация может быть на самом деле быстрее, потому что, хотя есть дополнительные издержки для синхронизации, другие потоки, пытающиеся получить доступ к переменной, будут ждать и просыпаться, когда наступит их очередь, а не повторять операцию несколько раз.

3 голосов
/ 07 февраля 2011

Это , а не бесконечный цикл, это хорошая практика при работе с алгоритмом TAS (тестирование и настройка).Цикл делает (а) чтение из памяти (должна быть изменчивая семантика) (б) вычисление нового значения (в) запись нового значения , если старое значение не изменилось за это время .

В базе данных это называется оптимистической блокировкой.Он использует тот факт, что большинство одновременных обновлений в совместно используемой памяти не требуются, и в этом случае это самый дешевый из возможных способов сделать это.

Фактически, это в основном то, что беспристрастная блокировка будет делать в неконтролируемойдело.Он будет читать значение блокировки, и если он разблокирован, он будет делать CAS идентификатора потока, и, если это успешно, блокировка теперь удерживается.Если это не удается, кто-то еще получил блокировку первым.Блокировки, однако, обрабатывают случай сбоя гораздо более изощренным способом, чем просто повторение операции снова и снова.Некоторое время они будут читать его, если блокировка быстро разблокируется (спин-блокировка), а затем, как правило, засыпают, чтобы пропустить другие потоки до их поворота (экспоненциальное отключение).

3 голосов
/ 06 февраля 2011

Когда значение изменяется в другом потоке, get () и compareAndSet () могут видеть разные значения. Это то, о чем должна беспокоиться параллельная библиотека.

1 голос
/ 06 февраля 2011

Вот фактическое использование операции compareAndSet: представьте, что вы разрабатываете алгоритм, который вычисляет что-то в нескольких потоках.

Каждый поток запоминает старое значение и на его основе выполняет сложный расчет.

Тогда он хочет установить новый результат ТОЛЬКО, если старое значение еще не было изменено другим потоком вычисления. Если старое значение не является ожидаемым, поток отбрасывает свою собственную работу, принимает новое значение и перезапускает вычисления. Для этого используется compareAndSet.

Далее другие потоки гарантированно получат только новые значения для продолжения вычислений.

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

Ура! * * 1013

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...