I have a task to do a synchronized Set using synchronized key word. Here's my realization
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SyncSet<T> implements Set<T> {
Set<T> set;
public SyncSet() {
set = new HashSet<>();
}
public SyncSet(int size) {
set = new HashSet<>(size);
}
public SyncSet(Collection<T> collection) {
set = new HashSet<>(collection);
}
@Override
public synchronized int size() {
return set.size();
}
@Override
public synchronized boolean isEmpty() {
return set.isEmpty();
}
@Override
public synchronized boolean contains(Object o) {
return set.contains(o);
}
@Override
public synchronized Iterator<T> iterator() {
return set.iterator();
}
@Override
public synchronized Object[] toArray() {
return set.toArray();
}
@Override
public synchronized <T1> T1[] toArray(T1[] a) {
return set.toArray(a);
}
@Override
public synchronized boolean add(T t) {
return set.add(t);
}
@Override
public synchronized boolean remove(Object o) {
return set.remove(o);
}
@Override
public synchronized boolean containsAll(Collection<?> c) {
return set.containsAll(c);
}
@Override
public synchronized boolean addAll(Collection<? extends T> c) {
return set.addAll(c);
}
@Override
public synchronized boolean retainAll(Collection<?> c) {
return set.retainAll(c);
}
@Override
public synchronized boolean removeAll(Collection<?> c) {
return set.removeAll(c);
}
@Override
public synchronized void clear() {
set.clear();
}
}
But when I run this code a lot of times, then sometimes it doesn't work like a synchronized set. For example, if i put 1000 different elements in it in one thread, and then delete all 1000 elements in another thread. And repeat it 1000 times, the set wouldn't be empty in a few times. Here's how I use it
public class Main {
private static void task1() {
Set<Integer> testSet = new SyncSet<>();
// Set<Integer> testSet = new HashSet<>();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; ++i) {
testSet.add(i * 10);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; ++i) {
testSet.remove(i * 10);
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(testSet.size());
}
public static void main(String[] args) {
IntStream.range(0, 1000)
.forEach(el -> {
System.out.print(el + ": ");
task1();
});
}
}