Concurrency / Synchronisation / ConcurrentModificationException
- September 2, 2019
- 1 reply
- 8974 views
Hi everybody,
Thingworx for sure supports concurrency. I quite often see all the different Thread IDs in the Script Log.
But I reached a point in Thingworx Script Development where I get concurrent conflicts and race conditions. Where are the synchronisation primitives to handle this?
The use case:
We have continous running machine providing it's data to twx via the KepServer. Tags of main interest are running meter, speed and timestamps of certain events.
Now we want to do some aggregation in memory and so I implemented an info table as property of the thing and a timer that frequently calls a service that just accumulates the total meters and the time to the last row of the infotable.
For certain events (e.g. change of reel) we now need to create a new row in the infotable and now I run into trouble, as the service to accumulate and the events leading to a new row are not on the same thread.
This lead to synchronisation issues, why I implemented a second infotable as a queue where the events are just stored. Afterwards the timer checks the queue for new rows and creates them. So now creation of row and the accumulation are on the same thread again. Should be OK, ... but it is not. I still get "ConcurrentModificationException".
The test/challange:
I found an article here that gave me some info on this issue:
https://community.ptc.com/t5/ThingWorx-Developers/Concurrency/m-p/502299
"To get a lock you need to update a persistent property, if you update a persistent no one will update that Thing until the service you are it's done."
With this information I did a quite brutal test (see attached Thing):
- This thing has a persistant and a not persistant property of type Integer.
- The service IncrementCounterAsyn increments both properties, first the persisted one.
- Between the two increments it calls a passive wait "pause(100)" which still should leave the thing locked
- The service ConcurrentIncrementCounter call the service IncrementCounterAsync 100 times in a loop.
- Waits for 2 Seconds and than returns the CounterValues ..
As the access to CounterMtx should lock the Thing all the async services should not be finished after 2 Sek. But they are ?
The final result for Counter & CounterMtx should be 100, but it never is. Indeed this is a "nice" random number generator. 😉
The question:
Ok how can I lock the Thing, that the final result is 100 for both Counter and CounterMtx??
I know that this test is quite stupid, but it's usefull to show and reproduce the issue.

