On 16 October 2014 17:34, Vladimir Sitnikov <[email protected]> wrote: >>> 2) Just synchronization on the same lock is not sufficient (see >>> "synchronizes-with" in the JMM) >>I don't follow that. > > Here's example: > Thread 1: > // Globals.state is a static non-volatile field > Globals.state = new AtomicInteger(42); // 42 is stored in a volatile > field, you can check that in java sources
But Globals.state is not final or volatile. > Thread 2: > System.out.println(Globals.state); > > Thread 2 _can_ print 0 and it would be _acceptable_ by JMM (including JMM8). > This is an example that shows that "not every volatile read synchronizes > with volatile write". How does that illustrate what you wrote here: "Just synchronization on the same lock is not sufficient" > There's a basic explanation: if a reader happened to "perform > synchronization" earlier than writer, then no happens-before appears. Yes, I took it as read that the volatile write has to happen before the read in order to publish the value safely. > More advanced one: to make things safe, you need happens-before. > "synchronization on the lock" does not induce happens before. "unlock of a > monitor happens-before _subsequent_ lock of the same monitor". Yes, I know. > This is why I say: "synchronization in execute" does nothing. There is no > way this synchronization ensures that this method would be executed after > the init method. True, but that would also affect single threaded code. > See more detailed explanation in [1] > >> (* apart from final, but I did write "mutable fields", which excludes > final) > > Even mutable field can be safely published if it is wrapped in a object > with a final field. > For instance, java.lang.String is always safe, however it contains char[] > that is both mutable and unsafe. > > Even if you store java.lang.String to a mutable field, it will still be > completely safe. I'm not sure I agree with that; the value of the mutable field needs to be published safely as well. > Nothing is specific to String, you can do the same with your own classes > and still get safe results (see [2]) > >>However these are external (*) to the class; changes to the app design >>may invalidate any such assumptions. > > Very true, however you must state threading contract in this kind of > classes. > JMeter is multithreaded by its nature, thus I would expect "guidelines for > writing a custom function" to be accompanied by a JMM semantics that is > ensured by JMeter engine. > For instance, "execute function might be called from multiple > threads simultaneously, however init is guaranteed to happens-before any > call to execute". > > Don't you mean that threading semantics of JMeter can change at any point > in time? > >> OK, but as already written, that is something over which the class has no > control. > > I did review some of the threading code in JMeter and I did notice some > code that already relied on the discussed JMeterThread.start happens-before. > > I do think it is worth to note in some developer's guide. > > However, I find it very natural that "JMeterThread state should not be > altered outside of the thread". > So any kind of "let's start the thread, then update some of its variables" > looks like a creepy code. Even if that is not yet forbidden explicitly in > the developer's guide. Agreed. > [1] > http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_publication > [2] http://www.slideshare.net/VladimirSitnikv/final-field-semantics > > Vladimir Sitnikov
