-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrent modification exceptions thrown when dynamically removing or adding controllers #72
base: master
Are you sure you want to change the base?
Conversation
…e ControllerList to prevent concurrent modification errors.
|
It's strange this library relies on Vector container. |
I did a bit of research and it sounds like (as with a lot of things Java) performance of synchronization was an issue in earlier JVMs but is unlikely to be in modern JVMs except for extreme cases. For the typical case of a single threaded application (as you indicate is usually the case in Processing) it appears the performance cost would be negligible: http://www.oracle.com/technetwork/java/6-performance-137236.html#2.1.1 "concurrency is considered an advanced technique among Processing users." Perhaps because handling concurrency is an advanced issue, and that Processing is intended for non-advanced users, it should not be up to the user to deal with it. There are cases where concurrency can become an issue without the user being aware of it. For example the reason I came across this issue is because we're developing a Processing library that automatically generates sets of ControlP5 Controllers based on data from a file or other data source. The library uses a thread to monitor changes to the data source and sometimes must update the available Controllers in response. Ideally the synchronization of this process with the rendering of control elements would be hidden from the user. I'm not sure how I'd go about externally synchronizing the with the automatic rendering of control elements, other than by synchronizing the draw method in a sketch (which seems like a very coarse grained synchronization). Is there some way to prevent control elements from rendering automatically and rendering them manually (thus being able to synchronize just that portion of the rendering process)? |
Yes, I was also very surprised to see Vector used! I assumed the library must be fairly old. My first attempt at a fix for the issue I'm having was to replace these with an ArrayList wrapped via Collections.synchronizedList(), but of course this doesn't prevent modifications while an Iterator is in use. |
Like I've mentioned, Java deprecated class Vector b/c it was unnecessarily |
|
"Like I've mentioned, Java deprecated class Vector b/c it was unnecessarily synchronized everywhere." Indeed, I later remembered that the old Vector class was in fact already liberally synchronized and so my first attempt was completely pointless. ;) "you're spreading synchronized even to methods w/o loops!" Yes I realised at 3am last night that I'd synchronized every method dealing with the controllers field, including ones that don't modify or iterate over the lists in ControllerList, oops. :P I figured if the general approach was approved then I'd update the request. "Given they're of datatype Vector, it means they're already synchronized. The only thing lacking then is to always safeguard them when they're being iterated. Though I dunno much about this library, I'm gonna try to come up w/ something more precise" Yes, two Vectors in ControllerList. If synchronisation is such a performance killer (perhaps it's not given the library has been using Vectors the whole time ;) ), perhaps the thing to do is replace the Vectors with (unsynchronized) ArrayLists, and synchronize as necessary in ControllerGroup (and anything else that uses ControllerList, if necessary)? |
That's a much more refined approach. But it can be modified later in some follow-up pull request at any time. But now I'm gonna focus on ControllerList class only. |
Okay. In the meantime, is there a way to prevent control elements from rendering automatically and rendering them manually (thus being able to externally synchronize just that portion of the rendering process)? |
In order for You were right that Let's say your other Thread wants to run This approach emulates a single-threaded sketch, b/c everything which would crash under a diff. Thread is transferred to sketch's "Animation Thread". |
The workaround sounds workable, good idea, thanks. :) I've just figured out how to hook into the "Animation Thread" before it calls draw, and how ControlP5 automatically draws its controllers, so will use the same mechanism to implement the workaround invisible to the user. I'm new to Processing. |
Hi, I am currently not able to follow up on this immediately but will look into it. The library started all the way back in 2005, so it is fairly old but has been extended, maintained, convoluted and adapted to quite a lot of processing version over the years. |
Counter-proposal done. Lotsa refactors there: #73 |
I found this works: noLoop(); |
This is still a problem. Tried the noLoop/loop hack but even that doesn't help. Is this a "won't fix" issue? If so, then at least I and others would know to look for a different GUI library. |
Methods in ControllerGroup that modify or iterate over the ControllerList should be synchronized to prevent concurrent modification exceptions when dynamically removing or adding controllers. For example code like:
executing in a separate thread can result in: