if (frameCount != lastFrame) {
lastFrame = frameCount;
}
So, if fC = 23 and LF = 23, then nothing happens, But if fC = 24 and LF = 23, then LF is set to 24. So if you Print LF After that Statement it will always be equal to fC. Because fC is set at the start of a new Frame. Then itās checked if theyāre equal and so Lc will end up as equal to fC after the statement. But before it should be different by 1, unless itās only set every n Frame. Then the difference is n.
I think @neilcsmith is right and frameCount is cached before the while loop by the JVM. Compiler is free to do this, because there is no synchronization in your code and the compiler assumes there will be no changes from different threads. Delay causes the thread to sleep which probably - I am guessing - creates a memory barrier and the values changed in other threads get updated in your whyOwhy thread as well.
Another problem is that v.x is updated in the background thread, but the main thread might not see the changes.
Both of these problems happen because the access to these variables is not synchronized in your sketch.
To make programs behave in a predictable way, you must synchronize all access to data which is touched from multiple threads (except read-only data). A consequence of this is you canāt safely read or write any built-in variables from threads, because PApplet modifies them without synchronization and you canāt fix it from within your sketch. You need to create your own variables which you then make sure are properly synchronized.
Thatās definitely one possibility, although if so is going to be implementation / CPU specific - pretty sure itās not specified to create one.
Of course, another option is that theyāre both broken! Just one isnāt given time to show up. Aggressive compilation depends on threshold numbers (1000s) of times through a loop. A hard loop will hit that quickly. Add a sleep in and the compile threshold just might not be being reached in the observed time.
One of the biggest problems I see with multi-threaded examples here that donāt use synchronisation or volatiles is the assumption that because things work for a while theyāll carry on working.
Good point! If the only way of observing whether the frameCount value triggers the if clause is this then either or both could be the problem.
IMO, thatās what happens: delay() forces an update between the local Threadās cache & the main memory.
So thereās no need for any further types of synchronization (even volatile fields) if we use delay(), in case we just need all local fields to be updated to the main memory.
A tight loop w/o any delay(), besides hammering the CPU super hot nonstop, can make all changes to a field (or an arrayās index) to stay stuck in the current Threadās local cache memory.
This is just not true. Please stop giving people stupidly erroneous advice. There is a Java memory model spec. Follow it or donāt be surprised if at some point something might break.
For further reading, see the second and third paragraph of 17.3 here, which explicitly covers your point - Chapter 17. Threads and Locks
ā¦ the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
The main thing is: ādoes not have toā.
It means it isnāt obliged to, but still it has permission to do so!
implementors are free to go beyond the minimum specs, as long as the languageās spec doesnāt prohibit it.
And so far, Thread.sleep() (delay() in Processing) hasnāt failed to flush local cached fields to main memory for every single case where threads are used in Processing.
You canāt make a reliable concurrent program by testing it and saying that it works so the code is right. You have to be able to defend that everything is properly synchronized and accounted for.
Thatās the hard part of concurrency in Java: you canāt fiddle around until it seems to work, you have to know that your code is right.
Otherwise you get strange bugs which happen only sometimes, usually during exhibitions or performances. Good luck finding the source of the problem then
You have absolutely no basis to make that statement! You just havenāt observed it yet. And even if you have something that works despite the spec you canāt guarantee that running it on a different machine or OS or next point release of the JVM wonāt break it. Iāve been in enough conference talks and discussions with people involved with HotSpot not to trust a word you say on it!
Jakubās right, these are often things that donāt show up until long running in performances and exhibitions. Been there, got the T-shirt! PraxisLIVE actually started out because of this, not as a live programming environment, but as an actor-based architecture I could build projects with using a universal lock-free message passing system - all cross-thread communication routed through one place. Processing could really benefit from a simplified but similar mechanism - threading just confuses beginners (and non-beginners )