webForumDet fria alternativet

Map hjälp

3 svar · 226 visningar · startad av Viktor

ViktorMedlem sedan aug. 20021 752 inlägg
#1

Jag har följande kod i min connectionpool

long curTime=System.currentTimeMillis();
Connection conn=null;
ConnectionInfo ci=null;
Iterator iter=usedConnections.keySet().iterator();

while(iter.hasNext())
{
	conn=(Connection)iter.next(); 
	ci=(ConnectionInfo)usedConnections.get(conn);
	if((ci.getTime()+cleanInterval)<curTime)
	{
		try
		{
			usedConnections.remove(conn);
			if(ci.getExtra()==false)
				freeConnections.add(newConnection());
			conn.close();
		}
		catch(SQLException sql)
		{
		}
	}
}

problemet med den är att när jag har kört en "usedConnections.remove(conn);" samtidigt som jag kör loopen som går igenom alla objekt i "usedConnections" så får jag detta fel medelande

java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:762)
        at java.util.HashMap$KeyIterator.next(HashMap.java:798)
        at com.vgsoftware.util.database.DBConnectionPool.clean(DBConnectionPool.
java:272)
        at com.vgsoftware.util.database.Cleaner.run(DBConnectionPool.java:330)

Är det någon som kan hjälpa till och föröska hitta ett bättre sätt att bygga loppen på? Jag har tänkt och testat lite men kan inte komma på något sätt :(

/Viktor

phonkworksMedlem sedan juli 2001228 inlägg
#2

Du kan kanske samla de connections som ska tas bort i en ArrayList och köra remove på dom efter "usedConnections" loopen är klar.

mvh
phonk

sgtpepperMedlem sedan apr. 20007 588 inlägg
#3

En HashMap har s.k fail-fast iterators, det betyder i princip att itereringen dör om den underliggande collectionen modifieras under iterationen.

Det du borde göra är istället att använda den remove()-metod som finns på iterator-objektet vilken i sin tur tar bort objektet från den underliggande collectionen.

Din kod bör alltså se ut så här:

long curTime=System.currentTimeMillis();
Connection conn=null;
ConnectionInfo ci=null;
Iterator iter=usedConnections.keySet().iterator();

while(iter.hasNext())
{
	conn=(Connection)iter.next(); 
	ci=(ConnectionInfo)usedConnections.get(conn);
	if((ci.getTime()+cleanInterval)<curTime)
	{
		try
		{
			[b][red]iter.remove();[/red][/b]
			if(ci.getExtra()==false)
				freeConnections.add(newConnection());
			conn.close();
		}
		catch(SQLException sql)
		{
		}
	}
}

Jag har ingen möjlighet att prova detta just nu, men jag är hyffsat säker på att det är det som är problemet, så testa och se om det funkar!

ViktorMedlem sedan aug. 20021 752 inlägg
#4

Provat nu och det fungerar, tackar!

/Viktor

136 ms totalt · 3 externa anrop · v20260731065814-full.3ab8d573
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)