Боюсь, что то, что вы ищете, невозможно, потому что безопасность потоков - это свойство алгоритмов, а не свойство структур данных. Вот пример:
Допустим, в вашей библиотеке графов есть основной класс Graph
с множеством методов, каждый из которых synchronized
. Например, addVertex()
, removeVertex()
, addEdge()
, removeEdge()
и т. Д. Предположим также, что класс Vertex
имеет несколько полезных методов, таких как, например, getAdjacentEdges()
, которые также синхронизируются с Graph
. экземпляр.
Теперь ясно, потому что все синхронизировано, невозможно повредить структуру данных. Например, у вас никогда не будет ситуации, когда v.getAdjacentEdges()
дает вам ребро, которого на самом деле нет в графе, содержащем вершину v
. Структура графа всегда внутренне согласована благодаря его внутренней синхронизации.
Однако ваши алгоритмы, работающие на графике, все еще могут легко сломаться. Например, допустим, вы пишете:
for (Edge e : v.getAdjacentEdges()) {
g.removeEdge(e);
}
Вызов getAdjacentEdges()
является атомарным, как и каждый вызов removeEdge()
в цикле, но сам алгоритм - нет. Другой поток может добавить новое ребро рядом с v
, пока выполняется этот цикл, или удалить ребро, или что-то еще. Чтобы быть в безопасности, вам все еще нужен способ гарантировать, что цикл в целом является атомарным, а сам граф не может этого обеспечить.
Мой лучший совет, я думаю, это использовать JGraphT в сочетании с реализацией Akka STM (или аналогичной), чтобы вы могли писать свои алгоритмы без необходимости заранее определять, какие объекты будут нуждаться в блокировке , Если вы не знакомы с STM и его характеристиками производительности, Статья в Википедии на тему неплохо объяснит.