mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-20 19:20:04 +00:00
added synchronization in RaceStateChangedListeners with a working copy of listeners to avoid ConcurrentModificationException
Change-Id: I8875826f61f76cd55831e57a55afc043017a1d7c
This commit is contained in:
1 parent
405348cf6d
commit
66b5a093df
1 file changed
+37
-11
+37
-11
@@ -9,79 +9,105 @@ public class RaceStateChangedListeners extends HashSet<RaceStateChangedListener>
|
||||
|
||||
private static final long serialVersionUID = 2028183211903975659L;
|
||||
|
||||
@Override
|
||||
public boolean add(RaceStateChangedListener listener) {
|
||||
synchronized (this) {
|
||||
return super.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
synchronized (this) {
|
||||
return super.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a working copy that can safely be iterated over. While producing, holds this objects
|
||||
* monitor using {@code synchronized(this)} which teams with {@link #add(RaceStateChangedListener)} and
|
||||
* {@link #remove} which
|
||||
* also synchronized on {@code this} object.
|
||||
*/
|
||||
private Iterable<RaceStateChangedListener> getWorkingCopyOfListeners() {
|
||||
synchronized (this) {
|
||||
return new HashSet<>(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRacingProcedureChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onRacingProcedureChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onStatusChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTimeChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onStartTimeChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishingTimeChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onFinishingTimeChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishedTimeChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onFinishedTimeChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProtestTimeChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onProtestTimeChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdvancePass(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onAdvancePass(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishingPositioningsChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onFinishingPositioningsChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishingPositionsConfirmed(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onFinishingPositionsConfirmed(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCourseDesignChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onCourseDesignChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindFixChanged(ReadonlyRaceState state) {
|
||||
for (RaceStateChangedListener listener : this) {
|
||||
for (RaceStateChangedListener listener : getWorkingCopyOfListeners()) {
|
||||
listener.onWindFixChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user