webForumDet fria alternativet

Map hjälp

Javaur Java

3 svar · 226 visningar · startad av Viktor

Medlem sedan aug. 20021 752 inlägg
Frågan#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

Medlem 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

Medlem 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!

Medlem sedan aug. 20021 752 inlägg
#4

Provat nu och det fungerar, tackar!

/Viktor

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