Home arrow static arrow Java Programming [Archive] - Synchronize problem...please help...
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - Synchronize problem...please help...
This topic has 46 replies on 4 pages.    « Previous | 1 | 2 | 3 | 4 | Next »

Posts:6,147
Registered: 11/9/00
Re: Synchronize problem...please help...  
Jun 22, 2004 11:58 AM (reply 30 of 46)



 
If you've got a process started by a button click it's unlikely you want further clicks of the same button to launch a thread which then waits until the first thread finishes. That's going to be pretty confusing for the user.

The first thing you should do on such an button click is to disable the button. The worker thread then reenables the button when it ends. Meanwhile a flag blocks any click actions that get through due to timing problems.

By doing all the flag stuff on the dispatcher thread you don't need to synchronize at all.

Something like:

public void actionPerformed(ActionEvent e) {    if(workThread == null) {        myButton.setEnabled(false);        workThread = new Thread() {            public void run() {                  doWork();   // do the time consuming job                  SwingUtils.invokeLater(new Runnable() {                             public void run() {                                workThread = null;                                myButton.setEnabled(true);                                });                   }.start()       }    }
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 22, 2004 2:21 PM (reply 31 of 46)



 
Oh, I thought the code tswain posted was his way of
demonstrating that you do need to call notify even
without wait().

I already posed code which proves this but I guess you didn't read all the posts.
The code you were pointing out was legosa's attempt to prove I am wrong and I was
saying I don't think it applied.
Here is the proof. (Deadlock in bold.)

Full thread dump Java HotSpot(TM) Client VM (1.4.2_04-b05 mixed mode):

"DestroyJavaVM" prio=5 tid=0x00034e50 nid=0x10c waiting on condition [0..7fad8]

"Caller(1)" prio=5 tid=0x00a0b6d0 nid=0x3d0 waiting for monitor entry [2cdf000..2cdfd8c]
at SynchTest.synchedMethod(SynchTest.java:51)
- waiting to lock <0x1002c330> (a SynchTest)
at SynchTest$Caller.run(SynchTest.java:89)
at java.lang.Thread.run(Unknown Source)

"Caller(0)" prio=5 tid=0x00a0b570 nid=0x24c runnable [2c9f000..2c9fd8c]
at SynchTest.synchedMethod(SynchTest.java:51)
- waiting to lock <0x1002c330> (a SynchTest)
at SynchTest$Caller.run(SynchTest.java:89)
at java.lang.Thread.run(Unknown Source)

"Signal Dispatcher" daemon prio=10 tid=0x009f5378 nid=0x7e8 waiting on condition [0..0]

"Finalizer" daemon prio=9 tid=0x009bd278 nid=0x3d8 in Object.wait() [2b5f000..2b5fd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x10010498> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x10010498> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" daemon prio=10 tid=0x009bbe48 nid=0x150 in Object.wait() [2b1f000..2b1fd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x10010388> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
- locked <0x10010388> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=5 tid=0x009f36d0 nid=0x258 runnable

"VM Periodic Task Thread" prio=10 tid=0x009f7b98 nid=0xd4 waiting on condition
"Suspend Checker Thread" prio=10 tid=0x009f48e0 nid=0x6fc runnable

Once again, here is the example:

[code]
public class SynchTest
{
static int id = 0;

SynchTest()
{

}

public void run()
{
int z;
long maxIterations = 120;
Caller c1 = new Caller();
Caller c2 = new Caller();
int iteration1 = 0;
int iteration2 = 0;
// wait for threads to start
System.out.println("SynchTest()");
while(!c1.task.isAlive() && !c2.task.isAlive())
{
synchronized(this)
{
try{wait(100);}catch(InterruptedException ie){}
}
System.out.println("SynchTest waiting");
}
System.out.println("running");
//---------
for(z=0;z<maxIterations;z++)
{
synchronized(this)
{
try{wait(1000);}catch(InterruptedException ie){}
}
//----------
if(c1.iteration == iteration1 || c2.iteration == iteration2)
{
System.out.println("It deadlocked ");
System.exit(1);
}
System.out.println("c1="c1.iteration" c2="+c2.iteration);
iteration1 = c1.iteration;
iteration2 = c2.iteration;
}
}

public synchronized void synchedMethod()
{

}

public static void main(String args[])
{
// Just to make legosa happy I did this here.
// instead of in constructor. Even though It doesn't make
// one iota of difference.
SynchTest synchTest = new SynchTest();
synchTest.run();
}
//-----------
class Caller implements Runnable
{
String msg = "";
Thread task = null;
int iteration = 0;

Caller()
{
start();
}

public void start()
{
task = new Thread(this);
task.start();
}

public void stop()
{
task = null;
}

public void run()
{
Thread controlThread = Thread.currentThread();
System.out.println("Caller running");
task.setName("Caller("+(id++)+")");
while(controlThread == task)
{
//System.out.println(" caller running "+this.toString());
synchedMethod();
iteration++;
}
}
}

}

////////////// End SynchTest.java

So there you have the source and the Thread dump.
The code will always deadlock at synchMethod() it does take a while
here is the last output from the actual program..

c1=268060014 c2=272615050

So it did take many millions of times to deadlock, but deadlock it did.

If you add a notifyAll() to synchMethod() it will never crash.
That's it I am not gong to say any more about this. If everyone cannot figure
out that I am right there is nothing left I can do except come over to your house and
run the code in person :P

Then again maybe I just found a little known bug in the JVM which would mean everyone
was right. Whatever the spec says this deadlocks. With a notify it doesn't

Nonetheless, I have asked Sun for clarification of this issue once and for all.
One more thing to clarify . I don't have any problems with Threads at all.
They work perfectly for me 100% of the time

<DISCLAIMER>
(When not in a 30 hour debuggathon)
</DISCLAIMER>

(T)

 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 22, 2004 2:34 PM (reply 32 of 46)



 
I already posed code which proves this but I guess you didn't read all the posts.

Your code involves wait()***, which introduces wait-sets into our discussion which concerns only synchronization. It also has a few obvious bugs. Each of these two is a reason enough not to consider your thread dump seriously. Please write an example that does not use any wait()s.

The code you were pointing out was legosa's attempt to prove I am wrong and I was saying I don't think it applied.

That code was my response to an unrelated question from the OP, not from you.

In reply #23 you said "Please post some code that involves several Threads calling a synchronized method that doesn't deadlock. I will admit I have supposed wrongly when I have it proven to me and print a full public.

Jverd responded to that. Please either show it deadlock, point out what you do not like about it, or admit that you "supposed wrongly".
 

Posts:37,103
Registered: 3/30/99
Re: Synchronize problem...please help...  
Jun 22, 2004 3:39 PM (reply 33 of 46)



 
I already posed code which proves this but I guess
you didn't read all the posts.

Your code involves wait()***, which introduces
wait-sets into our discussion

Yeah. I thought you (tswain) were claiming that you had to call notify even if you didn't use wait. Nobody here is claiming that you don't ned notify if you use wait. I think I said at least twice that you need notify if and only if you use wait.
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 22, 2004 3:43 PM (reply 34 of 46)



 
I already posed code which proves this but I guess
you didn't read all the posts.

Your code involves wait()***, which introduces
wait-sets into our discussion which concerns

Wait sets are your friend.

only synchronization. It also has a few
obvious bugs.

You mean you think it has, but actually it works 100% perfectly and there are 0 bugs.

Each of these two is a reason enough
not to consider your thread dump seriously.

Please
write an example that does not use any wait()s.

The waits were in the parentThread to do a lazy poll
to report the iteration counts. This involes one integer
move which is supposed to be atomic.

Sorry folks; in my zeal to prove my point I neglected the obvious that
I had a for loop and not a for(;;) :/ Thus the SynchTest() Thread
was aborting (parent) Which would at once stop the Caller0 & Caller1
Threads. Ok so how come no one else noticed that :P

As is I have let it run for over 3 billion iterations with no deadlock.
Therefore I uncategorically renounce my prervious ill conceived advice and
shall henceforth and forthwith make no more such references to such
a misguided suppostion.

(T)

 

Posts:6,750
Registered: 1/25/04
Re: Synchronize problem...please help...  
Jun 22, 2004 3:46 PM (reply 35 of 46)



 
I feel compelled to compliment tswain for his admission of error. It's not often you see such forthrightness around here. :-)
 

Posts:37,103
Registered: 3/30/99
Re: Synchronize problem...please help...  
Jun 22, 2004 3:50 PM (reply 36 of 46)



 
I already posed code which proves this but I guess
you didn't read all the posts.

Your code involves wait()***, which introduces
wait-sets into our discussion which concerns

Wait sets are your friend.

No doubt wait()*** is useful. I (and apparently others) simply removed it from the discussion about deadlocks because we thought you had.
 

Posts:37,103
Registered: 3/30/99
Re: Synchronize problem...please help...  
Jun 22, 2004 3:51 PM (reply 37 of 46)



 
I feel compelled to compliment tswain for his
admission of error. It's not often you see such
forthrightness around here. :-)

Seconded. Too often these disagreements turn into pissing contests, with nobody willing to back down.
 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 22, 2004 3:54 PM (reply 38 of 46)



 
Your code involves wait()***, which introduces wait-sets into our discussion which concerns
Wait sets are your friend.

Quite. It's a tool for a job. However any code that involves wait()*** is irrelevant to our discussion, which started in reply #7 as

tswain > For example, the previous example will eventually deadlock because of lack of notification.
legosa> There is also lack of wait()***. Therefore notification is not needed.

You mean you think it has, but actually it works 100% perfectly and there are 0 bugs.

Static field id is read-increpent-written by two Caller threads without synchronization. The main thread accesses c1.iteration and c2.iteration, which are modified by separate Caller threads, again without synchronization. Unsynchronized access to non-volative data across threads has unpredictable semantics, per JLS chapter 17. Now tell me that unpredictable behaviour is what you intended.

I'm not too interested in debuging the code (including that missing loop you mentioned - not a bug?) because the use of wait() immediately renders it irrelevant.
 

Posts:37,103
Registered: 3/30/99
Re: Synchronize problem...please help...  
Jun 22, 2004 3:57 PM (reply 39 of 46)



 
Static field id is read-increpent-written by two

"increpent"? Is that when you seek forgiveness for one more sin?
 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 22, 2004 4:03 PM (reply 40 of 46)



 
"increpent"? Is that when you seek forgiveness for one more sin?

Nope. It's when you ask for one more delicious crepe at lunch.
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 23, 2004 12:21 PM (reply 41 of 46)



 
If you're wrong you're wrong; no use pretending otherwise unless you want a career in politics. ;)

Alright alright I eat humble pie, but I was only so persistant because I was certain I was right
and had tested this before.
When I went home last night (in a stunned state), I realized that in my other code I used
a wait() in another Thread on (this) which is the root of my original erronious conclusion.
I used the wait() because I only wanted to run when notified and not for(;;)
That was done in 2000 so I have sadly had this idea for some time.
I will be more careful and good luck catching me with something so dumb next time :P

(T)
 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 23, 2004 12:30 PM (reply 42 of 46)



 
Alright alright I eat humble pie

Good of you to say so - admitting a mistake seems beyond most people in this forum. Glad we worked it out in the end! :-)
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 23, 2004 1:00 PM (reply 43 of 46)



 
Your code involves wait()***, which introduces
wait-sets into our discussion which concerns
Wait sets are your friend.

Quite. It's a tool for a job. However any code that
involves wait()*** is irrelevant to our discussion,
which started in reply #7 as

tswain > For example, the previous example will
eventually deadlock because of lack of notification.
legosa> There is also lack of wait()***. Therefore
notification is not needed.

You mean you think it has, but actually it works
100% perfectly and there are 0 bugs.

Static field id is read-increpent-written by two
Caller threads without synchronization. The main
thread accesses c1.iteration and c2.iteration, which
are modified by separate Caller threads, again without
synchronization.
The static field never changes
If it is just one move which is a read, then it isn't needed.
A move is guaranteed to be atomic.

Unsynchronized access to
non-volative data across threads has unpredictable
semantics, per JLS chapter 17. Now tell me that
unpredictable behaviour is what you intended.
Yes I have read that. and it is correct except when considering
the move of a primitate which is guaranteed to be atomic.
Of course this will vary according to the platform, but if it is
an integer or less than the bus width of the specific platform,
the move is guranteed to not get preempted before
being completed. Arrays, of course always need synching.

Actually the unpredicable behavior was the fat that the run()
method eventually aborts and I neglected to cause
Caller0 & 1 to stop. Thus when I did the Thread dump
I would see the Callers halted. I neglected to notice
the main Thread had already stopped.

Finally there is a little cheat there in that The caller Threads
are inner classes and thus within the same memory context as the parent class (For lack of
a better description) thus refernceing id is a direct reference to SynchTest.id
from the Callers with no indirection

I'm not too interested in debuging the code (including
that missing loop you mentioned - not a bug?) because
the use of wait() immediately renders it irrelevant.
Thankfully you do't have to, thought someone could add Caller.stop()
calls on exit.

I use this technique in situations where I want to get a value
from a class variable without synchronization. 1 read = 1 move.
I don't use this value for any control logic but only to echo its value.
Because of this I don't think this is an issue, well I have not seen any
in the last 4 years.
Even if it was running on a platform where the read could get preempted because of an interrupt for example, sooner or later the move will still happen. Now there may be some
platforms where there are some wierd cache issues, but in my
tests on the PC which is my prime platform, this is not an issue.
BTW I do usually declare all my shared variables volatile;
ie: https://hyperview.dev.java.net/unbranded-source/browse/*checkout*/hyperview/www/nio_server/Linkable.java?rev=HEAD&content-type=text/plain
I was just in a hurry and I realized in this test case such would not be an issue.
I am not saying it was correct or there is not the portential for issues on
other platforms however.

I'll be double checking all my code just to make sure :)

Anyway on to something else hopefully so I can heal the pyshic wounds from this humble pieing :/
I have some new good things coming up so I am off to work on them.

(T)
 

Posts:6,750
Registered: 1/25/04
Re: Synchronize problem...please help...  
Jun 23, 2004 1:38 PM (reply 44 of 46)



 
Unsynchronized access to
non-volative data across threads has unpredictable
semantics, per JLS chapter 17. Now tell me that
unpredictable behaviour is what you intended.
Yes I have read that. and it is correct except when
considering
the move of a primitate which is guaranteed to be
atomic.

I'm probably not going to say this very well, but I'm hoping someone will come along and clean up after me. :-) Just because it's atomic doesn't mean there are no potential threading issues, right? I think you say as much later on in this post. Something about how every thread is guaranteed to see either the before value or after and not an in-between value, but the order of things could be wrong. Or something like that.

Of course this will vary according to the platform,

Actually if you're talking about atomicity, I think that's not true - the spec requires it except for doubles and longs.

Finally there is a little cheat there in that The
caller Threads
are inner classes and thus within the same memory
context as the parent class (For lack of
a better description) thus refernceing id is a
direct reference to SynchTest.id
from the Callers with no indirection

I think this is not true - synthetic methods are generated to allow the inner class access to the enclosing class's fields (and vice-versa I guess).

I have some new good things coming up so I am off to
work on them.

Good for you! :-)
 
This topic has 46 replies on 4 pages.    « Previous | 1 | 2 | 3 | 4 | Next »