Java-метод синхронизации и взаимного исключения чтения/записи
У меня есть два метода read()
и write()
, как показано ниже в классе.
class Store
{
public void write()
{
// write to store;
}
public string read()
{
// read from store;
}
}
1) Объект Store
является одиночным.
2) У меня есть класс Writer
, который будет записываться в хранилище и несколько классов Reader
, которые будут считываться из хранилища одновременно.
Мое требование состоит в том, что, когда писатель пишет в магазин, все читатели должны ждать. то есть, когда управление находится в write()
, все вызовы на read()
должны быть заблокированы. Как мне это достичь? Я пробовал synchronize(Store.class)
в методе write()
, но для меня это не похоже.
Ответы
Ответ 1
Лучшим вариантом в этом случае является использование блокировки чтения-записи: ReadWriteLock. Он позволяет использовать один сценарий, но несколько параллельных считывателей, поэтому он является наиболее эффективным механизмом для этого типа сценариев.
Пример кода:
class Store
{
private ReadWriteLock rwlock = new ReentrantReadWriteLock();
public void write()
{
rwlock.writeLock().lock();
try {
write to store;
} finally {
rwlock.writeLock().unlock();
}
}
public String read()
{
rwlock.readLock().lock();
try {
read from store;
} finally {
rwlock.readLock().unlock();
}
}
}
Ответ 2
synchronized
- это самое простое решение, поэтому вы должны объяснить, что вы подразумеваете под "не похоже на работу для меня" и, возможно, покажите нам, как вы его использовали.
Лучшее решение - использовать ReentrantReadWriteLock, поскольку он позволяет одновременно получать доступ к читателям.
Ответ 3
Когда метод синхронизируется на каком-либо объекте, поток, выполняющий этот метод, блокирует все другие потоки, которые пытаются ввести другой блок/метод , который синхронизируется на одном и том же объекте.
Итак, если вы хотите, чтобы потоки писем запрещали читать любой поток читателей, вы должны синхронизировать как метод записи, так и метод чтения. Нет причин для синхронизации в классе Store. Синхронизация объекта Store более естественна:
public synchronized void write() {
write to store;
}
public synchronized String read() {
read from store;
}
Это, однако, (может быть) имеет недостаток: он также запрещает чтение двух потоков считывателей одновременно. Если вам это действительно нужно, вы должны использовать ReadWriteLock. Но это приведет к тому, что код будет менее производительным, а сложнее понять и сохранить. Я бы использовал его только в том случае, если бы я измерил, что это необходимо.
Ответ 4
Использовать ReadWriteLock из пакета java.util.concurrent