Interlocked-конструкции
Как мы выяснили, метод
Read
класса
Volatile
выполняет атомарную операцию
чтения, а метод
Write
этого же класса осуществляет атомарную операцию записи. То
есть каждый метод выполняет
либо
атомарное чтение,
либо
атомарную запись. В этом
разделе мы поговорим о статических методах класса
System.Threading.Interlocked
.
Каждый из этих методов выполняет как атомарное чтение, так и атомарную запись.
Кроме того, все методы класса
Interlocked
ставят барьер в памяти, то есть любая
запись переменной перед вызовом метода класса
Interlocked
выполняется до этого
метода, а все чтения переменных после вызова метода выполняются после него.
Статические методы, работающие с переменными типа
Int32
, безоговорочно
относятся к наиболее часто используемым. Продемонстрируем их:
public static class Interlocked {
// Возвращает (++location)
1
Кстати, Microsoft Visual Basic не содержит встроенной семантики volatile.
833
Конструкции.пользовательского.режима
public static Int32 Increment(ref Int32 location);
// Возвращает (--location)
public static Int32 Decrement(ref Int32 location);
// Возвращает (location += value)
// ПРИМЕЧАНИЕ. Значение может быть отрицательным,
// что позволяет выполнить вычитание
public static Int32 Add(ref Int32 location, Int32 value);
// Int32 old = location; location = value; возвращает old;
public static Int32 Exchange(ref Int32 location, Int32 value);
// Int32 old = location1;
// если (location1 == comparand) location = value;
// возвращает old;
public static Int32 CompareExchange(ref Int32 location,
Int32 value, Int32 comparand);
...
}
Существуют и перегруженные версии этих методов, работающие со значени-
ями типа
Int64
. Кроме того, в классе
Interlocked
существуют методы
Exchange
и
CompareExchange
, принимающие параметры
Object
,
IntPtr
,
Single
и
Double
.
Есть и обобщенная версия, в которой обобщенный тип ограничен типом
class
(любой ссылочный тип).
Лично мне очень нравятся
Interlocked
-методы, потому что они работают
относительно быстро и позволяют многого добиться. Давайте рассмотрим код,
использующий данные методы для асинхронного запроса данных с различных
веб-серверов. Это короткий код, не блокирующий никаких потоков, автоматически
масштабируемый с использованием потоков пула и использующий все доступные
процессоры, если их загрузка может пойти ему на пользу. Кроме того, количе-
ство серверов, на которые код в исходном виде поддерживает доступ, достигает
2 147 483 647 (
Int32.MaxValue
). Другими словами, это превосходная основа для
написания собственных сценариев.
internal sealed class MultiWebRequests {
// Этот класс Helper координирует все асинхронные операции
private AsyncCoordinator m_ac = new AsyncCoordinator();
// Набор веб-серверов, к которым будут посылаться запросы
// Хотя к этому словарю возможны одновременные обращения,
// в синхронизации доступа нет необходимости, потому что
// ключи после создания доступны только для чтения
private Dictionary m_servers = new Dictionary {
{ "http://Wintellect.com/", null },
{ "http://Microsoft.com/", null },
{ "http://1.1.1.1/", null }
};
public MultiWebRequests(Int32 timeout = Timeout.Infinite) {
продолжение
834
Do'stlaringiz bilan baham: |