[concurrency-interest] concurrency puzzle

David Holmes dcholmes at optusnet.com.au
Mon Sep 11 22:54:23 EDT 2006


Kevin,

I don't know if this answers your question but unsafe-publication arising
from deserialization would seem to be no different to unsafe-publication
arising from direct construction. In botrh cases bad things can happen.

Cheers,
David Holmes

> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Kevin
> Condon
> Sent: Tuesday, 12 September 2006 7:06 AM
> To: dholmes at ieee.org
> Cc: concurrency-interest at cs.oswego.edu
> Subject: Re: [concurrency-interest] concurrency puzzle
>
>
> > Wow! That is a very subtle distinction. I'm not sure there are
> any practical
> > consequences arising from it but I find it disconcerting to have this
> > difference.
>
> This isn't *exactly* the same thing, but I think there is a practical
> consequence for a similar situation when populating non-serialized
> fields in readObject().  For some Serializable class MyObject:
>
>   private transient Object mutex;  // needs to be volatile
>   private int f;
>
>   public MyObject() {
>     initTransient();
>   }
>
>   private void readObject(ObjectInputStream in) throws ... {
>     initTransient();
>     synchronized (mutex) {
>       in.defaultReadObject();
>     }
>   }
>
>   private void initTransient() {
>     // bad, no synchronization on the non-volatile field init
>     mutex = new Object();
>   }
>
>   private void writeObject(ObjectOutputStream out) throws ... {
>     // NPE, mutex init visiblility not guaranteed in all threads
>     synchronized (mutex) {
>       out.defaultWriteObject();
>     }
>   }
>
>   public int getF() {
>     // NPE, mutex init visiblility not guaranteed in all threads
>     synchronized (mutex) {
>       return f;
>     }
>   }
>
>   public void setF(int f) {
>     // NPE, mutex init visiblility not guaranteed in all threads
>     synchronized (mutex) {
>       this.f = f;
>     }
>   }
>
> T1:
>   volatile MyObject o;
>   ...
>   o = (MyObject) in.readObject();
>
> T2:
>   int v = o.getF();  // might get a NPE due to race on mutex value
>   // same NPE potential with o.setF() and with serializing the object ...
>
> If I didn't have to serialize, I'd just make mutex final.  I think
> making mutex volatile fixes the problem with potential NPEs, but then
> you incur performance costs for both synchronization and volatile
> semantics.  Is there some other option that I'm missing?  (Please
> assume I don't want to do synchronize (this), because more complex
> classes might not want to expose internal locks to avoid deadlock.)
>
> This scares me because it's so easy to forget to do (I definitely
> have) and because of the performance costs imposed (even if they may
> be small).  In general remembering to synchronize properly during
> construction and deserialization is just too easy to forget.
>
> Regards,
> Kevin
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the Concurrency-interest mailing list