Not that I have seen. I have noticed that (at least the iSeries) c compiler warns you if you link any function that is not threadsafe. I'd be trying very hard to avoid this as it's likely to bite you.
As long as you are avoiding things like static variables and non threadsafe functions, why would you need thread synchronisation?
No global/static variables. Using the api jdeCallObjectThreaded / jdeCallObjectThreadedJoin you can absolutely break a BSFN that maintains some kind of state using something like jdeCache. I was hoping that jdeCacheFetchForUpdate and jdeCacheFetchPositionForUpdate would synchronize on the jdeCache record, but it apparently doesn't - I believe I have proved this. I straight up broke some jdeCache code using jdeCallObjectThreaded. Once I implemented a mutex lock the problem resolved.
I am sure that the jdeCache APIs themselves are threadsafe but
jdeCacheFetchForUpdate / jdeCacheFetchPositionForUpdate or (jdeCacheFetch / jdeCacheFetchPosition)
...do some stuff
will break in a truly parallel processing situation.
I think jdeCallObjectThreaded / jdeCallObjectThreadedJoin may be the only use case that I am aware of in the JDE architecture that can result in true parallel processing of a BSFN for a given user session (key emphasis on "for a user session"). Even multiple instances of the same APPL with async type events effectively call BSFNs in a single thread for a given user session as far as I can tell so for the most part I think it is a moot point... I think I did find that one edge case though...
They really don't have much of a use case. They were added in TR126.96.36.199 I think. Look for "JD_Edwards_EnterpriseOne_In-Memory_Tools_C_API_Reference.pdf" on Oracle's support site, it documents them. I think I have used them more in testing stuff then in actual production code. I found that they sometimes increase total processing time (there is an initial cost I think to spin up the thread pool the first time you call them) and where they have decreased processing time the gains were nominal.
As you can't risk writing code that ties up a kernel they are of interest though. If you want to connect from a JDE server to some external thing at operating system level and don't need the return code this could be useful. In the past on iSeries I would just SBMJOB but now fewer and fewer customers are on that platform ...
Not that you care or that it matters, but just an FYI. From what I can tell, if you call jdeCallObjectThreaded (launches the bsfn thread) you have to call jdeCallObjectThreadedJoin (get thread/bsfn results)... jdeCallObjectThreaded is not a "fire and forget" call, jdeCallObjectThreaded uses up a slot in the user's thread pool and the thread is not released back to the thread pool until jdeCallObjectThreadedJoin is called. Also resources are allocated for the BSFN DS so failure to call jdeCallObjectThreadedJoin would result in a memory leak as well.