Необходимо синхронизировать доступ к двум разным коллекциям, доступным только через интерфейс.JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Необходимо синхронизировать доступ к двум разным коллекциям, доступным только через интерфейс.

Сообщение Anonymous »

(К вашему сведению, я не могу опубликовать рассматриваемый код)
У меня есть интерфейс

Код: Выделить всё

interface IEntity {
List getChildren(); //return list of children, safe to iterate i.e. a copy
List addChild(IEntity child); //add a child
List getParents(); //return list of parents, safe to iterate i.e. a copy
List addParent(IEntity parent); //add a parent
}
Требование состоит в том, чтобы родительские и дочерние списки оставались синхронизированными. Таким образом, каждый раз, когда вызывается addChild , внутренние компоненты метода должны гарантировать, что родительская коллекция дочернего элемента также обновляется. Потенциальный бесконечный цикл (addChild -> addParent -> addChild) можно разрешить, обновив внутреннюю коллекцию перед попыткой обновления соответствующего родительского/дочернего элемента.
Непотокобезопасный код относительно простой. Однако, если принять во внимание потокобезопасность, все становится сложнее. Я считаю, что ситуация тупика возникает, если каждый метод просто блокирует свою собственную коллекцию. например

Код: Выделить всё

addChild(IEntity child) {
synchronized(children) {
if(!children.contains(child)) {
...
child.addParent(this);
....
}
}
}
...
addParent(IEntity parent) {
synchronized(parents) {
if(!parents.contains(child)) {
...
parent.addChild(this)
...
}
}
Поскольку каждый экземпляр блокирует свою внутреннюю коллекцию, вышеупомянутый цикл (addChild -> addParent -> addChild) приводит к взаимоблокировке, поскольку блокировку необходимо получить до теста contains .
Похоже, что внутренние компоненты обоих методов addChild и addParent должны блокировать соответствующую коллекцию другого объекта, чтобы мы могли гарантировать, что при вызове метода выходит, коллекции синхронизированы. Однако ни один экземпляр не имеет прямого доступа к внутренним коллекциям. Все параметры типа интерфейса IEntity .
Я рассматривал возможность блокировки самого экземпляра, например. ...

Код: Выделить всё

addChild(IEntity child) {
synchronized(this) { //Always lock parent first to prevent deadlocks
synchronized(child) { //Generates a warning on locking method parameters
....
}
}
}

addParent(IEntity parent) {
synchronized (parent) { //Always lock parent first to prevent deadlocks
synchronized (this) { //Generates a warning on locking method parameters
...
}
}
}
Хотя я думаю, что это может сработать, похоже, что блокировка параметров метода опасна. Насколько я могу судить, проблема в этой теме отличается от этой. Так возможно ли, что это допустимое использование?
Отчасти это связано с тем, что реализация в некоторой степени пытается реализовать функцию, которая не полностью поддерживается интерфейсом. то есть интерфейс не предлагает способа заблокировать внутренние поля, но это необходимо для реализации. В определенной степени перепроектирование возможно.
Некоторые другие моменты:
  • это не объекты базы данных, поэтому Я не могу делегировать эту синхронизацию какому-либо другому компоненту.
  • Действительно, будут другие реализации этих объектов, поэтому необходимо использовать интерфейс.


Подробнее здесь: https://stackoverflow.com/questions/792 ... hrough-int
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»