Как синхронизировать запросы данных с процессом обновления данных? - PullRequest
0 голосов
/ 16 декабря 2008

У меня есть приложение, которое использует задание, похожее на cron, для обновления набора данных. Процесс обновления происходит раз в минуту и ​​не длится долго. Сервлет предоставляет этот набор данных пользователям. Моя проблема заключается в том, что в процессе обновления запросы сервлета должны блокироваться и ждать завершения процесса.

В нижней строке у меня есть эти две функции:

private void updateData() {    
}

public List getData() {
}

Первая функция запускается раз в минуту. Второй может быть вызван любое количество раз одновременно. При запуске updateData все вызовы getData должны ждать его завершения. Один вызов getData не должен блокировать последующие вызовы той же функции. Функция updateData имеет более высокий приоритет, чем getData, т.е. когда нужно запустить updateData, она должна ждать завершения всех вызовов getData, но запуск новых вызовов не должен разрешаться.

Какой механизм синхронизации я должен использовать для такого случая? Я использую сервер Java, но мне было бы интересно узнать, какие решения существуют и для других платформ.

Ответы [ 4 ]

5 голосов
/ 16 декабря 2008

Вы можете использовать ReadWriteLock вместо синхронизации.

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

public void updateData() {
    lock.writeLock().lock();
    try {
        /* do stuff. */
    } finally {
       lock.writeLock().unlock();
    }
}


public List getData() {
    lock.readLock().lock();
    try {
       /* process/return data. */
    } finally {
       lock.readLock().unlock();
    }

}

3 голосов
/ 16 декабря 2008

Посмотрите на эту статью: Блокировка чтения / записи в Java

Единственный недостаток, который я вижу в этом примере - это notifyAll (), который пробуждает все ожидающие потоки. Однако приоритет отдается запросам на блокировку записи.

0 голосов
/ 16 декабря 2008

CopyOnWriteArrayList или CopyOnWriteArraySet - это то, на что стоит обратить внимание. Я часто их использую в ситуациях, когда обновления происходят не часто.

0 голосов
/ 16 декабря 2008

Вам необходимо синхронизировать доступ к данным.

public void updateData() {
    synchronized (updateLock) {
        /* do stuff. */
    }
}


public List getData() {
    List data;
    synchronized (updateLock) {
        data = getRealData();
    }
    /* process/return data. */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...