[
https://issues.apache.org/jira/browse/FELIX-5443?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15728607#comment-15728607
]
Felix Meschberger commented on FELIX-5443:
------------------------------------------
Good catch. Current uses do not seem to trigger this much concurrency in this
context ...
How about replacing the internal set with an immutable variant:
{code}
Index: Factory.java
===================================================================
--- Factory.java (Revision 1773058)
+++ Factory.java (Arbeitskopie)
@@ -20,6 +20,7 @@
import java.io.IOException;
+import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
@@ -41,7 +42,7 @@
public static final String FACTORY_PID_LIST = "factory.pidList";
// the set of configuration PIDs belonging to this factory
- private final Set pids = new HashSet();;
+ private Set pids;
static boolean exists( PersistenceManager persistenceManager, String
factoryPid )
@@ -67,6 +68,7 @@
Factory( ConfigurationManager configurationManager, PersistenceManager
persistenceManager, String factoryPid )
{
super( configurationManager, persistenceManager, factoryPid );
+ this.pids = Collections.unmodifiableSet( Collections.emptySet() );
}
@@ -77,6 +79,7 @@
// set pids
String[] pidList = ( String[] ) props.get( FACTORY_PID_LIST );
+ HashSet pids = new HashSet();
if ( pidList != null )
{
for ( int i = 0; i < pidList.length; i++ )
@@ -84,6 +87,7 @@
pids.add( pidList[i] );
}
}
+ this.pids = Collections.unmodifiableSet( pids );
}
@@ -101,19 +105,25 @@
Set getPIDs()
{
- return new HashSet( pids );
+ return this.pids;
}
boolean addPID( String pid )
{
- return pids.add( pid );
+ HashSet pids = new HashSet();
+ boolean added = pids.add( pid );
+ this.pids = Collections.unmodifiableSet( pids );
+ return added;
}
boolean removePID( String pid )
{
- return pids.remove( pid );
+ HashSet pids = new HashSet();
+ boolean removed = pids.remove( pid );
+ this.pids = Collections.unmodifiableSet( pids );
+ return removed;
}
@@ -120,6 +130,7 @@
void store() throws IOException
{
Hashtable props = new Hashtable();
+ Set pids = this.pids;
if ( !pids.isEmpty() )
{
{code}
This allows us to optimize the {{getPids()}} method which is presumably called
more often than {{addPid}} and {{removePid}} which become more expensive.
> Frequent Changes cause UpdateThread to ConcurrentModificationException
> ----------------------------------------------------------------------
>
> Key: FELIX-5443
> URL: https://issues.apache.org/jira/browse/FELIX-5443
> Project: Felix
> Issue Type: Bug
> Components: Configuration Admin
> Affects Versions: configadmin-1.8.8
> Reporter: Fabian Lange
>
> 2016-11-30T10:20:15.614+0000 | ERROR | 836-1bc8-4066-963b-9b9cbccbd9d0) |
> configadmin | org.apache.felix.configadmin - 1.8.8 | Unexpected problem
> executing task java.util.ConcurrentModificationException at
> java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)[:1.8.0_101] at
> java.util.HashMap$KeyIterator.next(HashMap.java:1461)[:1.8.0_101] at
> java.util.AbstractCollection.toArray(AbstractCollection.java:196)[:1.8.0_101]
> at
> org.apache.felix.cm.impl.Factory.store(Factory.java:126)[4:org.apache.felix.configadmin:1.8.8]
> at
> org.apache.felix.cm.impl.ConfigurationManager$DeleteConfiguration.run(ConfigurationManager.java:1851)[4:org.apache.felix.configadmin:1.8.8]
> at
> org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:143)[4:org.apache.felix.configadmin:1.8.8]
> at
> org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:110)[4:org.apache.felix.configadmin:1.8.8]
> at java.lang.Thread.run(Thread.java:745)[:1.8.0_101]
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)