Thread synchronization

C

Chris Uppal

xarax said:
32-bit updates and fetches are atomic.

The fetches and updates are atomic, but since there's no guarantees about when
they'll happen (in the absence of synchronisation or volatile variables), that
fact is of almost /zero./ use in practise.

If the 32-bit value is an object reference then clearly the atomicity is
valueless since there's no guarantee that the data "pointed to" will be become
visible across thread boundaries at the same time, so we can only be talking
about int-s (and similar). Even there, you can't avoid synchronisation
usually. Here's an example from the Java Memory Model JSR:

http://www.cs.umd.edu/~pugh/java/memoryModel/PublicReview.pdf

Two threads, two shared variables A and B, two passages of code that access
them without synchronisation:

Initially A == B == 0

Thread 1:
r2 = A;
B = 1;

Thread 2:
r1 = B;
A = 2;

A legal result of this is that r2 == 2 and r1 == 1. The JSR describes this as
"surprising behavoir". Which is a classic bit of understatement...

-- chris
 
C

Chris Uppal

Mike said:
No, it's that any class C can do a

synchronized(o)

on any object o it has access to. If that object is also synchronizing on
itself, this can play havoc with its internal synchronization logic.
Note that this is independent of how well the internal synchronization is
encapsulated, or of whether the object's class is visible to C.

As far as I can see, this is the same as I was asking; am I still
misunderstanding you ?

I don't think

private Object lock_object();

synchronized(lock_object)

differs in concept from

synchronized(this)

particularly when you understand the reason for it.

Well, there are two possibilities that I can see. One is that you are putting
the "edges" of synchronisation in the same places I would (i.e. the externally
visible temporal behaviour of all the visible objects is the same whether it's
coded in your style or mine). If that is the case then the difference is
clearly fairly minor -- by definition -- but I would question why you are
choosing an relatively more obfuscated and potentially error-prone (e.g.
forgetting to make the lock object "final", as above ;-) expression, when Java
has a built-in expression that is easier to work with, and which does not
suggest that the program /might/ be doing something more complex than it
appears. The other possibility is that you are designing your synchronisation
networks in a way that I would not, and that your synchronisation does not
primarily follow object boundaries. If that is the case then I think that you
/are/ increasing the conceptual load, and even edging towards synchronisation
spaghetti, and while I'm sure /you/ can make it work well, it's not an approach
that I'd recommend in general.

[re: "Effective Java"]
I recommend it. My experience was that some of it was well-known and
obvious, while other parts were new and valuable.

I shall take another look next time I'm in the Big City. Thanks.

-- chris
 
M

Mike Schilling

Chris Uppal said:
As far as I can see, this is the same as I was asking; am I still
misunderstanding you ?

No, I think I was misunderstanding you. If by "execute a synchronised block
on the object in question", you mean what I described as

synchronized(o)

then, yes, we're talking about the same thing.
Well, there are two possibilities that I can see. One is that you are
putting
the "edges" of synchronisation in the same places I would (i.e. the
externally
visible temporal behaviour of all the visible objects is the same whether
it's
coded in your style or mine). If that is the case then the difference is
clearly fairly minor -- by definition -- but I would question why you are
choosing an relatively more obfuscated and potentially error-prone (e.g.
forgetting to make the lock object "final", as above ;-) expression,

Why is it important that it be final? It's a good idea not to change it, of
course :)
when Java
has a built-in expression that is easier to work with, and which does not
suggest that the program /might/ be doing something more complex than it
appears.

That's largely a question of idiom. Once you're used to seeing private lock
objects, the sight of another one no longer makes that suggestion. And I
prefer it purely for safety; the same reasons I make almost all fields
private.
 
M

Mike Schilling

Does anyone know the status of JSR 133 (fixing the Java memory model) ? It
was intended to be part of 1.5, but since the final vote was only two days
ago, that seems unlikely.
 
T

Thomas G. Marshall

Chris Uppal coughed up:
Lee said:
Thomas G. Marshall wrote:
...[rip]...

By 'rip', I assume that means that [...]

I think Thomas uses "rip" where another would use "snip". I admit
that when I first saw it, I took it as insulting -- something like
"we don't need all /this/ crud".

Nah. I use ...[sniped out stupidity]... for that :) And at least the
notion of text removal of it was clear.

And I don't use ...[rip]... all the time. Sometimes I use ...[stomp]... :)

No "crud" implication intended. I'm sorry that you took it that way.
 
T

Thomas G. Marshall

Lee Fesperman coughed up:

....[rip]...

I was saving a few electrons, since you are loath to back down on
even the smallest detail.

....by not showing that you removed lines to make it seem as if the
conversation occurred without it? That is dishonest, and you should know
better than to do that in usenet.

Apologies but I just cannot let you continue this crap. Do the ad hominem
thing all you like for this, but your tone is far to insulting again to let
you try to hand wave away your mistakes as if they did not occur, and
pretend that you were on correct footing when doing so.

I was wrong when I said that this thread was too twisted for me. You have
not made so twisted that I cannot stop you from continuing this charade.

You insist, so I'll bother some electrons...
You used "synchronization structure" without a modifier. That is
imprecise and confusing. Java is in the C language family. In the C
family, structure without a modifier refers to a data block.

The modifier was "synchronization".

A class
in Java is conceptually a structure with behavior. A better term is
synchronization block (referring to a code block), though
synchronized block is really to the point.

"Structure" (particularly since there is no such data construct in java) can
apply to any organization of code if used as an adjective, (but it is not
required). "Structured Programming", for example, does /NOT/ imply the use
of C data structures. Or are you saying it does???? You can also refer to
the structure of someone's code.

I used the term "Synchronization Structure", in that example specifically
because I wanted to make sure that it was understood that I am referring to
/both/ synchronization blocks /and/ synchronization methods. It is clear,
and you seem content to say it is I splitting hairs, when you are the one
attempting (and failing) to do so.

....[rip]...

Yes it was not clear. You explicitly stated that lines of code not
within the block were not synchronized.

And when you asked what I meant (as shown above):

LF:
By /within/, do you mean --- lines of code textually
inside the braces of a synchronization block (or
synchronized method)?

I made it very clear:

TGM:
The execution of such lines of code. Yep.

As usual, it is you try to twist meanings around and play the word games.

....[rip]...
 
T

Thomas G. Marshall

Mike Schilling coughed up:
Does anyone know the status of JSR 133 (fixing the Java memory model)
? It was intended to be part of 1.5, but since the final vote was
only two days ago, that seems unlikely.

Do you find the JSR's easy to navigate? I find it almost as confusing as
the RFC lightyear long collection. Particular to your point, I find it
almost impossible to figure out when something "made it" and into what
revision.
 
T

Thomas G. Marshall

Mike Schilling coughed up:

....[rip]...

And I prefer it purely for safety; the same reasons I
make almost all fields private.

That last one is a particularly good practice.

I am not one to /fully/ fall for the time honored "do not externally modify
an objects attributes". But I've seen my share of horrendous abuses of such
things to make sure that /no one/ touches the guts of an object without me
"knowing" about it.
 
T

Thomas G. Marshall

Chris Uppal coughed up:
class MyClass
{
private int ourThing thingness = 0;
public synchronised get() { return thingness; }
public synchronised increment(int by) { thingness += n; }
// TODO: is this really needed ?
public synchronised set(int n) { thingness = n; }
}

but it's doubtful whether I'd provide a public set() method unless
there was clear need for both set() and increment() as public
operations.

Put into my terms. Instances of MyClass accept responsibility for
ensuring that they can be increment()-ed in a thread-safe manner. It
is not the /caller's/ responsibility to do so.

I hear you on your concern here.

You may notice that this leads to broadening of the interface of
MyClass -- I'm entirely happy with that. Such broadening is (IMO)
natural in decent OO code. (As an aside, much Java code is not -- in
this specific sense, and IMO -- very well written. The received
wisdom is to keep classes lean, and to put the logic in the caller.
But I think that just leads to a mess where responsibility does not
properly follow object boundaries.


As I pointed out already, I too am worried about the potential lack of
documentation concerning the locking details within an object.

But your interface expansion notion does not hold for existing classes
beyond your control. Say you need to pull something out of a collection or
even a GUI table in one section and move it to another? This operation:

Entry entry = thang.grab(someplace);
thang.set(entry, elsewhere);

Is hugely thread unsafe. If you don't do this:

synchronized(thang)
{
Entry entry = thang.grab(someplace);
thang.set(entry, elsewhere);
}

then you might wish to make sure that all access goes through another method
of your own construction elsewhere...

//unified control to Things
public class SafeThingMutator
{
// you prefer synced methods, so ok, I'll use a general
// operation sync supplied by another poster...
public static synchronized
void modify(Runnable operation)
{
operation.run();
}
}

....but what if the Thing is part of a larger Swing GUI element that makes
its /own/ modifications to Thing on its own. /That/ wouldn't go through
your protection routine.

These are common issues. What would you do?
 
T

Thomas G. Marshall

Andrew Thompson coughed up:
On Wed, 15 Sep 2004 11:30:44 GMT, Thomas G. Marshall wrote:
..
...[sniped out stupidity]...

Is that the process of removing dumb people
from the population with the help of a
bell-tower and a high powered rifle? ;-)

lol. OI. Somedays....
 
X

xarax

"Thomas G. Marshall" <[email protected]>
wrote in message /snip/
As I pointed out already, I too am worried about the potential lack of
documentation concerning the locking details within an object.

But your interface expansion notion does not hold for existing classes
beyond your control. Say you need to pull something out of a collection or
even a GUI table in one section and move it to another? This operation:

Entry entry = thang.grab(someplace);
thang.set(entry, elsewhere);

Is hugely thread unsafe. If you don't do this:

synchronized(thang)
{
Entry entry = thang.grab(someplace);
thang.set(entry, elsewhere);
}

then you might wish to make sure that all access goes through another method
of your own construction elsewhere...

//unified control to Things
public class SafeThingMutator
{
// you prefer synced methods, so ok, I'll use a general
// operation sync supplied by another poster...
public static synchronized
void modify(Runnable operation)
{
operation.run();
}
}

...but what if the Thing is part of a larger Swing GUI element that makes
its /own/ modifications to Thing on its own. /That/ wouldn't go through
your protection routine.

These are common issues. What would you do?

The "correct" solution is to put the "smarts" into
the object itself so that the client only tells
the object *what* to do, not *how* to do it.

Your "thang" object should have a separate method
that accepts the "someplace" and "elsewhere" parameters,
and performs the entire movement without the client
knowing the details of synchronization. Encapsulation
is a *good* thing.

When the client is forced to specify *how* to do
something, that is procedural programming, rather
than object-oriented programming. It also runs
the risk of breaking subclasses or general
contracts between the client and the class.

In most cases, when the class does not provide a method
to do the new procedural task, the class can be extended
to a subclass that can perform the procedural task. Or
a new class can be written that encapsulates the other
class with composition. Knowledge of the implementation
details of the class are centralized in one place, and
the client can then use the new method calls in many
places. If the implementation needs changing, it's only
changed in one place and the client's method calls are
unaffected.

OTOH, if the client was forced to sprinkle those
"synchronized(thang){}" blocks everywhere, it would
be a major headache to fix all those blocks when the
implementation details change sufficiently to break
the client's view of that implementation.

A simple-minded example is a client that has
an ArrayList and wants to create an array of
the elements. The client knows that all of
elements are a subtype of "Fubar".

{
Fubar[] fubars;

synchronized(arrayList)
{
final int kk;

kk = arrayList.size();
fubars = new Fubar[kk];
arrayList.toArray(fubars);
}
}

In the above code-snippet, the "arrayList"
variable refers to an ArrayList that is
shared by multiple threads. The client code
is forced to synchronize the list before
extracting the size and then extracting the
elements.

A better solution is to extend the ArrayList
class to add a new method:

public class MyArrayList
extends ArrayList
{
public Fubar[] getFubars()
{
Fubar[] result;

synchronized(this)
{
final int kk;

kk = size();
result = new Fubar[kk];
toArray(result);
}
return result;
}
}

Now, the client application can use an instance
reference type of MyArrayList, instead of an ArrayList.

Instead of a hard-coding synchronized(arrayList){}
blocks everywhere, the client simply calls the getFubars()
method, which performs the necessary synchronization
and returns the array. The client must use the
MyArrayList type, instead of a plain ArrayList
type.

btw: The MyArrayList class should probably use
the generics extension "extends ArrayList<Fubar>"
to ensure that the client only uses subtypes of
Fubar for the array elements. But that's another
topic...;)
 
T

Thomas G. Marshall

xarax coughed up:
"Thomas G. Marshall"


The "correct" solution is to put the "smarts" into
the object itself so that the client only tells
the object *what* to do, not *how* to do it.

Believe me, I prefer that utterly.

But you simply cannot always do that. What if you are dealing with a GUI
object that needs to update a collection behind the scenes, and the code is
not in your control?

And the multiple array list issue you point out here is flawed:

....[rip]...
A better solution is to extend the ArrayList
class to add a new method:

public class MyArrayList
extends ArrayList
{
public Fubar[] getFubars()
{
Fubar[] result;

synchronized(this)
{
final int kk;

kk = size();
result = new Fubar[kk];
toArray(result);
}
return result;
}
}

Now, the client application can use an instance
reference type of MyArrayList, instead of an ArrayList.

Flawed because the user can still use the ArrayList (superclass)
accessor/mutator methods behind your back. That would be very bad design.
Instead of extending ArrayList, do you mean extending some sort of
synchronized arraylist class (one that sync's on /this/ already)?

....[rip]...
 
M

Mike Schilling

Thomas G. Marshall said:
Mike Schilling coughed up:

...[rip]...

And I prefer it purely for safety; the same reasons I
make almost all fields private.

That last one is a particularly good practice.

I am not one to /fully/ fall for the time honored "do not externally
modify
an objects attributes". But I've seen my share of horrendous abuses of
such
things to make sure that /no one/ touches the guts of an object without me
"knowing" about it.

Absolutely. And in this context, I'll make this point once more. If,
instead of every Java object being a monitor, there was a Monitor class, and
you needed a monitor for each instance of class Foo, would you declare it
as:

public Monitor lock;

or

private Monitor lock;

There's no question, is there?

By the same token, between

synchronize(this) // any code at all can mess with the monitor

and

private final Object lock = new Object(); // Thanks for the suggestion
about final, Chris
synchronize(lock); // no one touches
this lock but me

there is again no question.
 
B

Babu Kalakrishnan

xarax said:
public class MyArrayList
extends ArrayList
{
public Fubar[] getFubars()
{
Fubar[] result;

synchronized(this)
{
final int kk;

kk = size();
result = new Fubar[kk];
toArray(result);
}
return result;
}
}

Two points :

a) This code isn't threadsafe (unless the class you're extending is a Vector).
If another thread calls add() on a MyArrayList instance between the size() call
and the toArray() call, "result" will no longer contain the data from the list.

b) The Collections framework is one of the rare cases in the Java library where
synchronization behaviour of classes is reasonally well defined and documented.
As for other complex objects (like say GUI classes, Threads, java.io classes
etc) there is precious little documentation available on whether the superclass
ever executes a method / block with synchronization on the "this" object at all.
So when discussing about the general advisability of synchronizing on "this", an
ArrayList or a Vector would be a bad example to use.

BK
 
X

xarax

Babu Kalakrishnan said:
xarax said:
public class MyArrayList
extends ArrayList
{
public Fubar[] getFubars()
{
Fubar[] result;

synchronized(this)
{
final int kk;

kk = size();
result = new Fubar[kk];
toArray(result);
}
return result;
}
}

Two points :

a) This code isn't threadsafe (unless the class you're extending is a Vector).
If another thread calls add() on a MyArrayList instance between the size() call
and the toArray() call, "result" will no longer contain the data from the list.

b) The Collections framework is one of the rare cases in the Java library where
synchronization behaviour of classes is reasonally well defined and documented.
As for other complex objects (like say GUI classes, Threads, java.io classes
etc) there is precious little documentation available on whether the superclass
ever executes a method / block with synchronization on the "this" object at all.
So when discussing about the general advisability of synchronizing on "this", an
ArrayList or a Vector would be a bad example to use.

Yes, you would have to override the other methods
and make them synchronized. But that was not my
point. The point was to encapsulate a series of
operations into one method, so that the method
can handle the threadsafety issues, rather than
the client.
 
T

Thomas G. Marshall

xarax coughed up:
Babu Kalakrishnan said:
xarax said:
public class MyArrayList
extends ArrayList
{
public Fubar[] getFubars()
{
Fubar[] result;

synchronized(this)
{
final int kk;

kk = size();
result = new Fubar[kk];
toArray(result);
}
return result;
}
}

Two points :

a) This code isn't threadsafe (unless the class you're extending is
a Vector). If another thread calls add() on a MyArrayList instance
between the size() call and the toArray() call, "result" will no
longer contain the data from the list.

b) The Collections framework is one of the rare cases in the Java
library where synchronization behaviour of classes is reasonally
well defined and documented. As for other complex objects (like say
GUI classes, Threads, java.io classes etc) there is precious little
documentation available on whether the superclass ever executes a
method / block with synchronization on the "this" object at all. So
when discussing about the general advisability of synchronizing on
"this", an ArrayList or a Vector would be a bad example to use.

Yes, you would have to override the other methods
and make them synchronized. But that was not my
point. The point was to encapsulate a series of
operations into one method, so that the method
can handle the threadsafety issues, rather than
the client.

Override /all/ of the accessor/mutator's and methods with similar side
effects? Unless there is a protected/public common subroutine to all of
them, IMHO you've now created a technique that is adding more potential
instability than you were trying to avoid in the first place.

Interestingly (to me at least) there /are/ inner classes called, for one
example, Collections.SynchronizedCollection, etc. But it is declared with
package scope, so you cannot extend it.
 
X

xarax

"Thomas G. Marshall" <[email protected]>
wrote in message /snip/
Override /all/ of the accessor/mutator's and methods with similar side
effects? Unless there is a protected/public common subroutine to all of
them, IMHO you've now created a technique that is adding more potential
instability than you were trying to avoid in the first place.

Only the public methods would be overridden with
synchronized variants.

A better solution is to wrap the ArrayList within
a new class that only has methods that are of interest
to the client application. The wrapper instance is
shared among the threads, instead of the raw ArrayList
instance.
Interestingly (to me at least) there /are/ inner classes called, for one
example, Collections.SynchronizedCollection, etc. But it is declared with
package scope, so you cannot extend it.

Hmmm, I can't find that class in the JavaDoc for 1.4.2.
 
T

Thomas G. Marshall

xarax coughed up:
"Thomas G. Marshall"


Only the public methods would be overridden with
synchronized variants.

A better solution is to wrap the ArrayList within
a new class that only has methods that are of interest
to the client application. The wrapper instance is
shared among the threads, instead of the raw ArrayList
instance.

And just make sure to have that new class implement List if you want it to
be compatible to all the other List cognizant sections of the jdk.

Hmmm, I can't find that class in the JavaDoc for 1.4.2.


For 1.4.2_05? Look in the source:

mumble/java/util/Collections.java, line 1518.

Like I said though, it's a package scope thing. So it's not for general
usage.

You could copy it out and use it I suppose, but you'd have to be careful to
make sure that it changes with the collection api's should they change (like
they did for generics support in 1.5).
 
M

Mike Schilling

Thomas G. Marshall said:
xarax coughed up:

And just make sure to have that new class implement List if you want it to
be compatible to all the other List cognizant sections of the jdk.




For 1.4.2_05? Look in the source:

mumble/java/util/Collections.java, line 1518.

Like I said though, it's a package scope thing. So it's not for general
usage.

You could copy it out and use it I suppose, but you'd have to be careful
to
make sure that it changes with the collection api's should they change
(like
they did for generics support in 1.5).

This is presumably the type returned by Collections.synchronizedCollection()
? How would you want to use it other than by calling that method?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top