Hi all
I got two diffrent version of java file:
public class TreadInConstructor implements Runnable {
private static int cnt = 0;
public TreadInConstructor() {
Thread.yield();
cnt++;
}
public void run() {
try {
Thread.sleep(30);
new TreadInConstructor();
} catch (Exception e) {}
return;
}
public static void main(String[] args) throws Exception {
int millis = 10000;
TreadInConstructor tic = new TreadInConstructor();
for(int i = 0 ; i < 1000; i++) new Thread(tic).start();
Thread.sleep(millis);
System.out.println("cnt = " + cnt);
}
}
and the second one
public class TreadInConstructor2 implements Runnable {
volatile private static int cnt = 0;
public TreadInConstructor2() {
synchronized (TreadInConstructor2.class) {
Thread.yield();
cnt++;
}
}
public void run() {
new TreadInConstructor2();
return;
}
public static void main(String[] args) throws Exception {
int millis = 10000;
TreadInConstructor2 tic = new TreadInConstructor2();
for(int i = 0 ; i < 10000; i++) new Thread(tic).start();
Thread.sleep(millis);
System.out.println("cnt = " + cnt);
}
}
Now I'm expecting that the synchronized block in the constructor will
accomodate any conflicting access to the static cnt member and the
version without any synchronization will not run right
(that is the program won't print 10001).
The point is that I don't see any differences.
In a dual processor pc will they run without any differences?
If so why?
Thanx in advance
Robert Klemme - 25 Nov 2005 16:15 GMT
> Hi all
> I got two diffrent version of java file:
[quoted text clipped - 53 lines]
>
> Thanx in advance
Most likely the non synchronized version happens to work ok
"accidentally". While requirements for JVM's are rather loose in this
case you still might get correct results. But it's not guaranteed so you
better stick with synchronized access.
Btw, why do you have a Thread.yield() in your code? I don't think any
other thread (apart from main maybe) will run because all other threads
with constructors will be blocked by the synchronization.
A last remark: I'd put the changing code for the static var in a static
synchronized method - that keeps concerns (i.e. dealing with instance
scope state and class scope state) separated nicely.
Kind regards
robert
Thomas Hawtin - 25 Nov 2005 16:25 GMT
> Now I'm expecting that the synchronized block in the constructor will
> accomodate any conflicting access to the static cnt member and the
[quoted text clipped - 3 lines]
> In a dual processor pc will they run without any differences?
> If so why?
The first example may give low values of the counter even on single
threaded hardware. It depends upon very close timings, so the error may
well be difficult to detect. ++ is not necessarily atomic, but it is
generally fast.
In general, you need to ensure thread-safety by inspection, as it is the
sort of thing testing may well not pick up even if your system fails in
the field.
You are mixing of volatile and synchronized. Usually one or the other.
For a counter you can use java.util.concurrent.atomic.AtomicInteger/
AtomicIntegerFieldUpdater for better performance than synchronisation.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
bg - 01 Dec 2005 09:39 GMT
> Hi all
> I got two diffrent version of java file:
[quoted text clipped - 53 lines]
>
> Thanx in advance
The basic reason you don't see any difference is that cnt++ is an atomic
operation - ie the other thread won't interupt it. Also it doesn't
matter what order the cnt++ operations are executed in - the result will
always be the same as long as there is the same number of them.
try something like this instead of cnt++ to see a difference:
int a=cnt;
Thread.sleep(100);
cnt = a+1;
Robert Klemme - 01 Dec 2005 10:00 GMT
>> Hi all
>> I got two diffrent version of java file:
[quoted text clipped - 58 lines]
> result will always be the same as long as there is the same number of
> them.
This is not only about interruption and order but about consistency of
state in memory. Without proper synchronization it is allowed (from the
language spec point of view) that there are two thread local copies of the
original state, both are incremented and only one of them wins. If thread
safety is a must, you must use some form of synchronization (or use
volatile in some circumstances). Period.
Kind regards
robert
Chris Uppal - 01 Dec 2005 11:42 GMT
> The basic reason you don't see any difference is that cnt++ is an atomic
> operation - ie the other thread won't interupt it.
That is simply untrue.
-- chris