Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
//...
void readerFn()
{
synchronized (mutex.reader)
{
atomicOp!"+="(numReaders, 1);
rdSemA.notify();
rdSemB.wait();
atomicOp!"-="(numReaders, 1);
}
}
void writerFn()
{
synchronized (mutex.writer)
{
atomicOp!"+="(numWriters, 1);
wrSemA.notify();
wrSemB.wait();
atomicOp!"-="(numWriters, 1);
}
}
// ...
scope group = new ThreadGroup;
// 2 simultaneous readers
group.create(&readerFn); group.create(&readerFn);
rdSemA.wait(); rdSemA.wait();
assert(numReaders == 2);
rdSemB.notify(); rdSemB.notify();
group.joinAll();
assert(numReaders == 0);
foreach (t; group) group.remove(t);
А проблем тестирования самих акторов в случае с isolated mutability я не вижу, нужно тестировать реакцию на различные сообщения независимо от наличия очереди, точно так же как в однопоточном варианте.
в варианте неблокирующего оптимистичного алгоритма есть существенный недостаток: при высокой конкуренции вероятность получить false на compare-and-swap становится достаточно высока, особенно с большими значениями BigInteger
Кроме того, пожалуй, метод val() излишний в api, потому что класс в таком виде становится не Thread safe
Поэтому приложение должно уметь отлавливать такие случаи и повторять попытку изменений с самого начала. Практически нигде в примерах это даже не упоминается
Если да, то нас опередили, но мы оптимистичны и повторяем транзакцию еще раз.
private final TransactionFactory txFactory = new TransactionFactoryBuilder().setMaxRetries(1_000_000) .build();
Atomic<BigInteger> curr (или как там в Java) и отказаться от synchronized в get.
Concurrency: 6 способов жить с shared state