Java multi-threading & Safe Publication

2018-12-31 20:25发布

问题:

After reading \"Java concurrent in practice\" and \"OSGI in practice\" I found a specific subject very interesting; Safe Publication. The following is from JCIP:

To publish an object safely, both the reference to the object and the object\'s state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer.
  • Storing a reference to it into a volatile field.
  • Storing a reference to it into a final field.
  • Storing a reference to it into a field that is properly guarded by a (synchronized) lock.

My first question: how many java developers are aware of this (problem)? How many real world java applications are really following this, AND is this really a real problem? I have a feeling that 99% of the implemented JVMs out there are not that \"evil\", i.e. a thread is not guaranteed (in fact its practical (almost) \"impossible\") to see stale data just because the reference is not following the \"safe publication idiom\" above.

回答1:

Proportionally, it\'s probably fair to say that very few programmers sufficiently understand synchronization and concurrency. Who knows how many server applications there are out there right now managing financial transactions, medical records, police records, telephony etc etc that are full of synchronization bugs and essentially work by accident, or very very occasionally fail (never heard of anybody get a phantom phone call added to their telephone bill?) for reasons that are never really looked into or gotten to the bottom of.

Object publication is a particular problem because it\'s often overlooked, and it\'s a place where it\'s quite reasonable for compilers to make optimisations that could result in unexpected behaviour if you don\'t know about it: in the JIT-compiled code, storing a pointer, then incrementing it and storing the data is a very reasonable thing to do. You might think it\'s \"evil\", but at a low level, it\'s really how you\'d expect the JVM spec to be. (Incidentally, I\'ve heard of real-life programs running in JRockit suffering from this problem-- it\'s not purely theoretical.)

If you know that your application has synchronization bugs but isn\'t misbehaving in your current JVM on your current hardware, then (a) congratulations; and (b), now is the time to start \"walking calmly towards the fire exit\", fixing your code and educating your programmers before you need to upgrade too many components.



回答2:

\"is this really a real problem?\"

Yes absolutely. Even the most trivial web application has to confront issues surrounding concurrency. Servlets are accessed by multiple threads, for example.

The other issue is that threading and concurrency is very hard to handle correctly. It is almost too hard. That is why we are seeing trends emerge like transactional memory, and languages like Clojure that hopefully make concurrency easier to deal with. But we have a ways to go before these become main stream. Thus we have to do the best with what we have. Reading JCiP is a very good start.



回答3:

Firstly \"safe publication\" is not really an idiom (IMO). It comes straight from the language.

There have been cases of problems with unsafe publication, with use of NIO for instance.

Most Java code is very badly written. Threaded code is obviously more difficult than average line-of-business code.



回答4:

It\'s not a matter of being \"evil\". It is a real problem, and will become much more apparent with the rise of multicore architectures in the coming years. I have seen very real production bugs due to improper synchronization. And to answer your other question, I would say that very few programmers are aware of the issue, even among otherwise \"good\" developers.



回答5:

I would say very few programmers are away of this issue. When was the last code example you have seen that used the volatile keyword? However, most of the other conditioned mentioned - I just took for granted as best practices.

If a developer completely neglects those conditions, they will quickly encounter multi-threading errors.



回答6:

My experience (short-terming and consulting in lots of different kinds of environments Most applications I\'ve seen) agrees with this intuition - I\'ve never seen an entire system clearly architected to manage this problem carefully (well, I\'ve also almost never seen an entire system clearly architected) . I\'ve worked with very, very few developers with a good knowledge of threading issues.

Especially with web apps, you can often get away with this, or at least seem to get away with it. If you have spring-based instantiations managing your object creation and stateless servlets, you can often pretend that there\'s no such thing as synchronization, and this is sort where lots of applications end up. Eventually someone starts putting some shared state where it doesn\'t belong and 3 months later someone notices some wierd intermittent errors. This is often \"good enough\" for many people (as long as you\'re not writing banking transactions).

How many java developer are aware of this problem? Hard to say, as it depends heavily on where you work.