### Question:
DependencyGraph { public List<T> topologicalSort() throws CyclicDependencyException { lock.readLock().lock(); try { ArrayList<T> result = new ArrayList<>(); Deque<T> noIncomingEdges = new ArrayDeque<>(); Map<T, Integer> temp = new HashMap<>(); for (Map.Entry<T, Set<T>> incoming : incomingEdges.entrySet()) { int size = incoming.getValue().size(); T key = incoming.getKey(); temp.put(key, size); if (size == 0) { noIncomingEdges.add(key); } } while (!noIncomingEdges.isEmpty()) { T n = noIncomingEdges.poll(); result.add(n); temp.remove(n); Set<T> elements = outgoingEdges.get(n); if (elements != null) { for (T m : elements) { Integer count = temp.get(m); temp.put(m, --count); if (count == 0) { noIncomingEdges.add(m); } } } } if (!temp.isEmpty()) { throw new CyclicDependencyException("Cycle detected"); } else { return result; } } finally { lock.readLock().unlock(); } }  List<T> topologicalSort(); void addDependency(T from, T to); void removeDependency(T from, T to); void clearAll(); boolean hasDependent(T element); Set<T> getDependents(T element); void remove(T element);  }### Answer:
@Test public void testEmpty() throws CyclicDependencyException { assertTrue(new DependencyGraph().topologicalSort().isEmpty()); }
@Test public void testConcurrentAccess() throws Exception { DependencyGraph<String> graph = new DependencyGraph<>(); ExecutorService service = Executors.newCachedThreadPool(getTestThreadFactory("Worker")); try { CountDownLatch startLatch = new CountDownLatch(1); int threads = 20; ArrayList<Future<?>> futures = new ArrayList<>(); for (int i = 0; i < threads; i++) { futures.add(submitTask("A", "B", startLatch, service, graph)); futures.add(submitTask("A", "C", startLatch, service, graph)); futures.add(submitTask("A", "D", startLatch, service, graph)); futures.add(submitTask("A", "B", startLatch, service, graph)); futures.add(submitTask("D", "B", startLatch, service, graph)); futures.add(submitTask("D", "C", startLatch, service, graph)); futures.add(submitTask("C", "B", startLatch, service, graph)); } startLatch.countDown(); awaitAll(futures); } finally { service.shutdownNow(); } assertEquals(graph.topologicalSort(), Arrays.asList("A", "D", "C", "B")); }