Hi, 

With many high-level APIs there are no solid specified happens-before 
relations. However, there are two reasons that point towards the code being 
thread-safe: 

- The parameters are all captured variables. This means they are final in 
the anonymous class: https://javap.yawk.at/#YSqg0D/procyon - this gives you 
the guarantees of final fields, which should solve any thread safety issues 
in your example. I don't believe kotlin specifies this behavior, though. 

- Concurrency APIs **should** have a happens-before edge between task 
submission and execution, or you could easily shoot yourself in the foot. 
Stdlib Executor is the standard example for this: "Actions in a thread 
prior to submitting a Runnable object to an Executor happen-before its 
execution begins, perhaps in another thread." (
https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/concurrent/Executor.html).
 
I'm not familiar with reactor, and I doubt this behavior is specified 
anywhere in reactor, but it is reasonable to assume the same holds there. 

The immutability of the three parameters is not relevant to these two 
points. It is certainly helpful because you do not need to worry about 
safely publishing truly immutable objects, but it's less helpful than it 
may seem: Map in particular is often backed by a mutable map even though it 
is unmodifiable API, so the rules for immutable objects do not technically 
apply to it. 

(HashMap in particular has one final field: 
https://java-browser.yawk.at/java/14/java.base/java/util/HashMap.java#java.util.HashMap%23loadFactor
 
- with the implementation of final concurrency guarantees this **should** 
be enough to make safe publishing of HashMap objects unnecessary on 
hotspot, but this is again beyond the actual JMM rules.) 

Finally, if there are parallel executions of doOnNext and you are mutating 
one of the parameters, you may of course need synchronization then. But 
that is not what you asked. 

- Jonas 

Am Samstag, 18. April 2020 13:16:08 UTC+2 schrieb Jacob P:
>
> Hi,
>
> let's consider the following piece of code in Kotlin:
>
>
>     data class A(val params: Map<String, String>)
>
>     private fun f(a: A, str: String, map: Map<String, Any>): Mono<String> 
> {
>         Mono.just("")
>              .doOnNext {
>                    // do some action with a, str, map. These actions
>                    // are executed in other thread because of 
> `subscribeOn`. 
>                    // Let's call that thread T1
>               }
>             .subscribeOn(Schedulers.elastic())
>             .subscribe()
>     }
>
>
>     fun main(args: Array<String>){
>        f() // called with required parameters
>     }
>
>
>
>
> 1. Is is thread-safe? Why? 
> 2. How can be ensured that *T1 *sees completely initialized objects? 
> 3. What if one of arguments, for example *map* will be mutable?
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
To view this discussion on the web, visit 
https://groups.google.com/d/msgid/mechanical-sympathy/0db2edf2-3a5d-491a-92fe-32bbe02a7604%40googlegroups.com.

Reply via email to