Я видел вопрос How do determine if an object is locked (synchronized) so not to block in Java?
Но у меня есть проблема, по которой я не могу найти решение.
В моем веб-приложении есть процесс, в котором обновляется контейнер данных, и это может занять много времени. Обновление необходимо сделать с интервалом времени. Конечно, когда одно обновление все еще работает на контейнере, другое не может (чтобы не повреждать данные в контейнере).
Я хочу использовать фоновый поток для обновления контейнера. Несколько фоновых работников могут работать одновременно на нескольких контейнерах (разные рабочие для разных пользовательских сеансов, каждый пользовательский сеанс может иметь разные данные в своем контейнере).
Конечно, я могу сделать synchronize(myContainer)
в рабочем состоянии, чтобы любой другой рабочий не обновлял данный конкретный контейнер. Но я скорее хочу проверить, работает ли какой-либо рабочий над контейнером и выйдет, если есть. Также я бы не хотел менять код контейнера, поэтому я бы не хотел добавлять ReentrantLock внутри класса контейнера и блокировать его.
Итак, у рабочего есть MyContainer
экземпляр и вы хотите определить, обновляет ли какой-либо другой рабочий объект этот экземпляр контейнера.Как синхронизировать объект без блокировки?
Любые идеи, как достичь этого?
'ConcurrentLinkedQueue' является неблокирующим, что означает, что OP не является осторожным, цикл while может сделать серьезную занятость-поворот –
@John Vint Я предполагаю, что в очереди уже хранятся все контейнеры в то время, когда рабочие потоки запускаются, как в случае, если контейнеры немедленно добавляются в очередь или немедленно добавляются в другую очередь, которая затем чередуется с исходной очередью. Если это не так, лучше выбрать «BlockingQueue» - цикл в моем ответе не будет занят, если контейнеры будут одновременно добавлены и удалены из очереди, но это может привести к преждевременному прекращению использования. –
@JohnVint: На самом деле, мой ответ имеет тот же недостаток, но я думаю, что ограничение частоты обновления выходит за рамки этого вопроса, и у OP должно быть что-то, что можно было бы решить. В противном случае «ScheduledExecutorService» будет хорошим решением. –