[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Data sharing in java



> -----Original Message-----
> From: java-threads-request@xxxxxxxxx
> [mailto:java-threads-request@xxxxxxxxx]On Behalf Of Richard Beton
> Sent: dinsdag 9 mei 2000 18:46
> To: Java-Threads Mailing List
> Subject: Re: Data sharing in java
>
>
> Jeremy Martin wrote:
>
> > ...But I would
> > like to have some kind of design rules that give a formal guarantee
> > that no errors can arise due to data sharing, i.e. if the java program
> > were tranformed so that every assignment
> >
> >  A = B;
> >
> > were changed to
> >
> >  A = (B).clone();
> >
> > then the answer would be the same.
>
> I can't see how this could be possible, because
>
>  A = B;
>  A.radius = 24.0;
>
> and
>
>  A = (B).clone();
>  A.radius = 24.0;
>
> give different state (in the latter case, B.radius is not altered).
>
> Java uses its direct reference model to support closely the entity
> relationship modelling at the heart of O.O. In many cases, this is a clear
> benefit. But when it comes to writing multi-threaded programs, it
> can confuse
> matters somewhat. We have 'progressed' from the copy-assignment typical of
> earlier languages like occam and Ada; I sometimes wonder whether
> we are poised
> to progress onto another generation that encompasses concurrency
> rather better
> than O.O. does. Time will tell!
>
> Rick

Rick and Jeremy,

I remember that we talked about something similar in a discussion group at
the workshop in 1996 at Kent and we agreed that channel communication should
copy its contents from source to destination. Copy-by-value would be
superior to copy-by-reference for relative small messages. Each process
holds its own copy of the message and can alter the state of the message
object independently ? it's thread-safe and there are more benefits.
Sometimes sharing objects is necessary for efficiency (as Jeremy pointed
out). One must be careful with sharing objects when data can be updated
simultaneously as you know.
The Java people knew this problem and therefore they invented the wrapper
objects (e.g., java.lang.Integer, java.lang.Boolean, etc.) that are
read-only and cannot be altered. These wrappers are perhaps thread-safe but
their penalty in performance and memory management (garbage collecting) is
enormous.
The CTJ channels performs copy-by-value by using a special copy(..) method
that can copy the contents of an object to another object of the same type.
The CTJ channel calls the copy(..) method when both processes engage in the
communication event.
Also a reference can be copied by sending a proxy object that holds the
reference. So, copy-by-value can also perform copy-by-reference. For
example, proxy.object points to the message object to be sent (e.g.,
proxy.object = new Message()). The Channel_of_Proxy.write(proxy) operation
at the sender side will copy its contents (the reference) to the destination
proxy object at the receiver side on channel communication. The
Channel_of_Proxy.read(proxy) operation at the receiver side receives the
reference in proxy.object on communication. Special is that the
Channel_of_Proxy will clear the reference proxy.object (i.e., proxy.object =
null) at the sender side after communication. Thus, the sender will loose
its control over the object. Objects will be shared when the sender holds an
extra copy to the message object. It's up to the programmer.

Java does not allow us to copy the contents of a source object to a
destination object in a simple way. The Java clone(..) method is not a great
solution. The copy(..) method as mentioned above uses reflection (see
java.lang.reflect) that allows us to find variables in an object and alter
their contents. Reflection allows us to copy a variable of one object to a
variable of another object (e.g., A.radius = B.radius).

A.radius = 10.0;
B.radius = 2.0;
copy(B,A) ;      /* copy contents of B to A */
B.radius = 5.0; /* this will not effect the setting of A.radius */

The result is A.radius = 2.0 and B.radius = 5.0.

I belief that in a multithreaded environment shared objects must be
read-only or its data should be altered via synchronized methods. There is a
third option. CTJ has a special scheduler build-in that performs
non-preemptive scheduling for processes in a PAR construct (including nested
constructs) and performs preemptive scheduling when a PRIPAR is involved. A
shared object in a non-preemptive environment needs no synchronized methods,
because there is no scheduling until channel communication.

Jeremy, this may not give an answer to your questions, but CTJ gives an
alternative for copy-by-reference (typically Java), namely copy-by-value (as
in occam and Ada). CTJ does not give a solution about the side effects of
sharing objects. However, I agree that the copy-by-value approach (as in
occam, Ada and CTJ) contributes in a better reliable concurrency platform
for Java.

Gerald.