Why am i getting ConcurrentModificationException on this unmodifiableSet?









up vote
0
down vote

favorite












I'm getting a java.util.ConcurrentModificationException on the line where the for-loop starts (see comment in code).



Why am i getting ConcurrentModificationException on this unmodifiableSet?



final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());
if (!portSet.isEmpty())
StringBuilder tmpSb = new StringBuilder();
for (Port pp : portSet) // <------- exception happening here
tmpSb.append(pp.getNum()).append(" ");




I've never witnessed this, but I'm getting crash reports from Google.










share|improve this question

















  • 1




    Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
    – Slaw
    Nov 11 at 2:00










  • ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
    – Nick
    Nov 11 at 2:30










  • Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
    – Slaw
    Nov 11 at 2:53






  • 1




    The fine documentation.
    – chrylis
    Nov 11 at 2:54














up vote
0
down vote

favorite












I'm getting a java.util.ConcurrentModificationException on the line where the for-loop starts (see comment in code).



Why am i getting ConcurrentModificationException on this unmodifiableSet?



final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());
if (!portSet.isEmpty())
StringBuilder tmpSb = new StringBuilder();
for (Port pp : portSet) // <------- exception happening here
tmpSb.append(pp.getNum()).append(" ");




I've never witnessed this, but I'm getting crash reports from Google.










share|improve this question

















  • 1




    Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
    – Slaw
    Nov 11 at 2:00










  • ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
    – Nick
    Nov 11 at 2:30










  • Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
    – Slaw
    Nov 11 at 2:53






  • 1




    The fine documentation.
    – chrylis
    Nov 11 at 2:54












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm getting a java.util.ConcurrentModificationException on the line where the for-loop starts (see comment in code).



Why am i getting ConcurrentModificationException on this unmodifiableSet?



final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());
if (!portSet.isEmpty())
StringBuilder tmpSb = new StringBuilder();
for (Port pp : portSet) // <------- exception happening here
tmpSb.append(pp.getNum()).append(" ");




I've never witnessed this, but I'm getting crash reports from Google.










share|improve this question













I'm getting a java.util.ConcurrentModificationException on the line where the for-loop starts (see comment in code).



Why am i getting ConcurrentModificationException on this unmodifiableSet?



final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());
if (!portSet.isEmpty())
StringBuilder tmpSb = new StringBuilder();
for (Port pp : portSet) // <------- exception happening here
tmpSb.append(pp.getNum()).append(" ");




I've never witnessed this, but I'm getting crash reports from Google.







java android concurrency






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 1:54









Nick

1,08211321




1,08211321







  • 1




    Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
    – Slaw
    Nov 11 at 2:00










  • ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
    – Nick
    Nov 11 at 2:30










  • Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
    – Slaw
    Nov 11 at 2:53






  • 1




    The fine documentation.
    – chrylis
    Nov 11 at 2:54












  • 1




    Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
    – Slaw
    Nov 11 at 2:00










  • ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
    – Nick
    Nov 11 at 2:30










  • Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
    – Slaw
    Nov 11 at 2:53






  • 1




    The fine documentation.
    – chrylis
    Nov 11 at 2:54







1




1




Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
– Slaw
Nov 11 at 2:00




Can the Set returned by node.getOpenPorts() be modified by other code (not necessarily your own code)?
– Slaw
Nov 11 at 2:00












ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
– Nick
Nov 11 at 2:30




ok. i guess my assumption of Collections.unmodifiableSet making a copy of the set is wrong. I guess it just wraps and prevents add/removes?
– Nick
Nov 11 at 2:30












Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
– Slaw
Nov 11 at 2:53




Yes, the Collections.unmodifiableXXX methods all wrap the given collection. These wrappers delegate to the underlying collection for read operations, but throw UnsupportedOperationException for the write operations.
– Slaw
Nov 11 at 2:53




1




1




The fine documentation.
– chrylis
Nov 11 at 2:54




The fine documentation.
– chrylis
Nov 11 at 2:54












1 Answer
1






active

oldest

votes

















up vote
3
down vote



accepted










Something must be modifying the underlying set; i.e. the set returned by node.getOpenPorts().



Instead of wrapping the set with an "unmodifiable" wrapper, you could copy it.



 final Set<Port> portSet = new HashSet<>(node.getOpenPorts());


But as a commenter (@Slaw) pointed out, that just moves the iteration inside the constructor and you would still get CCMEs.



The only real solutions are:



  • Change the implementation of the node class to use a concurrent set class for the port list that won't throw CCMEs if the collection is mutated while you are iterating it.


  • Change the implementation of the node class to return a copy of the port list. Deal with the updates-while-copying race condition with some internal locking.


  • Put a try / catch around the code and repeat the operation if you get a CCME




I've never witnessed this, but I'm getting crash reports from Google.




Yes. The problem only occurs if this code is executed while the open port list is changing.






share|improve this answer






















  • Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
    – Slaw
    Nov 11 at 2:08











  • I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
    – Nick
    Nov 11 at 17:53










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245185%2fwhy-am-i-getting-concurrentmodificationexception-on-this-unmodifiableset%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










Something must be modifying the underlying set; i.e. the set returned by node.getOpenPorts().



Instead of wrapping the set with an "unmodifiable" wrapper, you could copy it.



 final Set<Port> portSet = new HashSet<>(node.getOpenPorts());


But as a commenter (@Slaw) pointed out, that just moves the iteration inside the constructor and you would still get CCMEs.



The only real solutions are:



  • Change the implementation of the node class to use a concurrent set class for the port list that won't throw CCMEs if the collection is mutated while you are iterating it.


  • Change the implementation of the node class to return a copy of the port list. Deal with the updates-while-copying race condition with some internal locking.


  • Put a try / catch around the code and repeat the operation if you get a CCME




I've never witnessed this, but I'm getting crash reports from Google.




Yes. The problem only occurs if this code is executed while the open port list is changing.






share|improve this answer






















  • Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
    – Slaw
    Nov 11 at 2:08











  • I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
    – Nick
    Nov 11 at 17:53














up vote
3
down vote



accepted










Something must be modifying the underlying set; i.e. the set returned by node.getOpenPorts().



Instead of wrapping the set with an "unmodifiable" wrapper, you could copy it.



 final Set<Port> portSet = new HashSet<>(node.getOpenPorts());


But as a commenter (@Slaw) pointed out, that just moves the iteration inside the constructor and you would still get CCMEs.



The only real solutions are:



  • Change the implementation of the node class to use a concurrent set class for the port list that won't throw CCMEs if the collection is mutated while you are iterating it.


  • Change the implementation of the node class to return a copy of the port list. Deal with the updates-while-copying race condition with some internal locking.


  • Put a try / catch around the code and repeat the operation if you get a CCME




I've never witnessed this, but I'm getting crash reports from Google.




Yes. The problem only occurs if this code is executed while the open port list is changing.






share|improve this answer






















  • Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
    – Slaw
    Nov 11 at 2:08











  • I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
    – Nick
    Nov 11 at 17:53












up vote
3
down vote



accepted







up vote
3
down vote



accepted






Something must be modifying the underlying set; i.e. the set returned by node.getOpenPorts().



Instead of wrapping the set with an "unmodifiable" wrapper, you could copy it.



 final Set<Port> portSet = new HashSet<>(node.getOpenPorts());


But as a commenter (@Slaw) pointed out, that just moves the iteration inside the constructor and you would still get CCMEs.



The only real solutions are:



  • Change the implementation of the node class to use a concurrent set class for the port list that won't throw CCMEs if the collection is mutated while you are iterating it.


  • Change the implementation of the node class to return a copy of the port list. Deal with the updates-while-copying race condition with some internal locking.


  • Put a try / catch around the code and repeat the operation if you get a CCME




I've never witnessed this, but I'm getting crash reports from Google.




Yes. The problem only occurs if this code is executed while the open port list is changing.






share|improve this answer














Something must be modifying the underlying set; i.e. the set returned by node.getOpenPorts().



Instead of wrapping the set with an "unmodifiable" wrapper, you could copy it.



 final Set<Port> portSet = new HashSet<>(node.getOpenPorts());


But as a commenter (@Slaw) pointed out, that just moves the iteration inside the constructor and you would still get CCMEs.



The only real solutions are:



  • Change the implementation of the node class to use a concurrent set class for the port list that won't throw CCMEs if the collection is mutated while you are iterating it.


  • Change the implementation of the node class to return a copy of the port list. Deal with the updates-while-copying race condition with some internal locking.


  • Put a try / catch around the code and repeat the operation if you get a CCME




I've never witnessed this, but I'm getting crash reports from Google.




Yes. The problem only occurs if this code is executed while the open port list is changing.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 at 2:24

























answered Nov 11 at 2:01









Stephen C

509k69554906




509k69554906











  • Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
    – Slaw
    Nov 11 at 2:08











  • I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
    – Nick
    Nov 11 at 17:53
















  • Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
    – Slaw
    Nov 11 at 2:08











  • I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
    – Nick
    Nov 11 at 17:53















Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
– Slaw
Nov 11 at 2:08





Doesn't this just move the iteration to inside HashSet? Based on OP's code, the act of copying seems just as likely to throw a ConcurrentModificationException.
– Slaw
Nov 11 at 2:08













I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
– Nick
Nov 11 at 17:53




I'm marking this as the answer, because what I need to do is replace my TreeSet with a ConcurrentSkipListSet. The Collections.unmodifiableSet is not needed. Thanks.
– Nick
Nov 11 at 17:53

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53245185%2fwhy-am-i-getting-concurrentmodificationexception-on-this-unmodifiableset%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto