Как насчет такого метода:
public <T> int drainTo(Set<? extends T> source, Collection<T> target) {
Iterator<? extends T> it = source.iterator();
int count = 0;
while (it.hasNext()) {
target.add(it.next());
it.remove();
count++;
}
return count;
}
public static void main(String[] args) throws Exception {
Collection<String> list = new ArrayList<>();
// HashSet<String> set = new HashSet<>();
Set<String> set = ConcurrentHashMap.newKeySet();
set.add("1");
set.add("2");
set.add("3");
new Thread(() -> {
set.add("4");
set.add("5");
}).start();
drainTo(set, list);
// could print [1, 2, 3] , [1, 2, 3, 4], or [1, 2, 3, 4, 5]
// since there's no guarantee that the thread finished putting all elements in yet
System.out.println(list);
}