public class RetryHandler extends Thread {
private ArrayList<RetryMessage> retryMessages;
private Object syncObject = new Object();
private RetryHandler() {
this.setName("retryhlr");
}
public Boolean addMessage(IfgExchangeRequestBase msg, int token) {
synchronized(syncObject) {
retryMessages.add(new RetryMessage(msg, token));
return true;
}
}
public Boolean removeMessage(Integer token) {
synchronized(syncObject) {
retryMessages.removeIf(x->x.getToken().equals(token));
return true;
}
}
@Override
public void run() {
while(isRunning) {
if (!isPaused) {
synchronized(syncObject) {
ListIterator<RetryMessage> tempRTMessages = retryMessages.listIterator();
while(tempRTMessages.hasNext()){
RetryMessage rtmsg =tempRTMessages.next();
if(....)) {
tempRTMessages.remove();
} else if(...)
try {
int token = fetch()
rtmsg.retried();
rtmsg.setToken(token);
} catch (SAGException e) {
}
}
}
}
}
}
}ConcurrentModificationException trotz der Verwendung von Iterator und synchronisiert
Wie Sie sehen RetryHandler Gewinde erstreckt, die retryMessages
über eine interne Liste iterieren. Trotz der Verwendung Iterator
und synchronized
bekomme ich ConcurrentModificationException
. addMessage
und removeMessage
wurde in anderen Threads
verwendet.
hinweis: I Verwendet ListIterator aber das ergebnis ist das selbe. und RetryMessage rtmsg =tempRTMessages.next();
löst diese Ausnahme aus.
UPDATE: Exception wirft auf RetryMessage rtmsg =tempRTMessages.next();
Sind Sie sicher, dass die '' retryMessages' list' nur über die 'addMessage' modifiziert und' removeMessage' Methoden? – Eran
Was macht 'fetch()'? –
Beachten Sie, dass es eine gute Idee ist, die endgültigen Mitglieder zu synchronisieren, damit Sie sie nicht versehentlich neu zuweisen können. –