У меня есть интерфейс
Код: Выделить всё
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(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 должны блокировать соответствующую коллекцию другого объекта, чтобы мы могли гарантировать, что при вызове метода выходит, коллекции синхронизированы. Однако ни один экземпляр не имеет прямого доступа к внутренним коллекциям. Все параметры типа интерфейса 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