There are several thread safety issues :
- if
size(),remove()andremoveAll()need towait(), they will throw anIllegalMonitorStateExceptionsince they do not hold the lock on this at the time they callwait(); - for that same reason, they may see stale values for
isUpdating - if
size()would be interrupted while waiting (supposing that gets fixed) its return statement would result in aNullPointerException. - while many threads may be waiting, only one will be notified when
isUpdatingis set tofalseagain, since you callnotify()instead ofnotifyAll() - operations such as
contains()andisEmpty()may see stale values since they are not properly synchronized. - when interrupted all overridden methods violate the
Setcontract. - the interrupted flag is cleared upon interruption since the InterruptedException is caught and the state is not set to interrupted again.
- not strictly a problem, but you synchronize on this. This means third party code locking on your
Setwill influence its behavior. It is preferrable to lock on a private Object.
I'm not sure what you mean exactly by 'proper size'.
Also, I think that if you properly implement this, you'll basically end up with the same behavior as what you'd get from Collections.unmodifiableSetsynchronizedSet(new LinkedHashSet())