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:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 20, 2004 10:26 PM (reply 15 of 46)



 
no one is correct 100% of the time. However, I am
not
going to believe something
just because someone says it.
...
1- Why would Sun make it a capability of the
language
if it is bad??
2- Why would Sun use it themselves if it is bad?

So are you believing something just because Sun said
it, or do you think Sun is right 100% of the time?
:-)

No they are only right and used in the appeal to authority method when people
want to use them to disagree with me If I disagree with them :P

<DISCLAIMER>
That was a joke eh.
</DISCLAIMER>

If I thought Sun was right 100% of the time I wouldn't keep saying I think
their code practices are bloated, non optimal, and severely constrained
despite the chorus of "there is never a need to optimize,
I might do a boo boo and make a bug, the sacred rules of encapsulation
may be contravened and the whole world end, or I could never do anything
obverse the textbook which, unlike Sun, is 100% always correct."

(T)
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 21, 2004 1:36 AM (reply 16 of 46)



 
Consider that if another Thread could get blocked if
it tries to get the Monitor while the other thread in
the synchronized method(). Would that Thread
automatically be able to get the Monitor without being
notified?

Yes. Notification is required only to wake up a
thread that is wait()***. Waiting for a monitor does
not involve wait()***.

I'm not sure what your code is trying to demonstrate,
but it exhibits a number of bad practices (like
leaking object reference form a constructor and

This is a single program to show deadlock between
2 threads using a synchronized method and not an exorcise
in reentrancy. The program gets run once and then aborts
and there is as such no issue with anything leaking.
I took the time to write it to demonstrate what I
was trying to explain to you so you would understand it
and didn't intend it as a locus of inter thread reference handling.

sharing variables between threads without
synchronization),

The method itself is synchronized. Were there
a notifyAll() at the end of the method it would never deadlock.
This is what I was trying to show you. You said there is never a need
for a notify unless someone is waiting.

so I woundn't be surprised if it
didn't do what you expected.

You missed the point because It does exactly what I expected which is deadlock because
"it lacks a notify before returning from synchronized method "whereas If you add a notify it
will never deadlock. (Barring a windows crash or other non relevant obscurity)

Conclusion: I am not covinced using synchronized
methods are dirty .

They are not. Making Runnable.run() synchronized to
solve OP's problem is. It's not the language feature
that's dirty, it's how one (mis)uses it.

You have a point there. I didn't mean to seem to imply that
it would. Here's one that addresses his issue.

/*    Here is something ot play with. It starts a given  amount of threads Each thread waits on a shared lock and notifys when it is done. The main Thread  does a thread.join() to wait on the last Thread. It could have joined and thus waited for >any< of those Threads. I set the default Thread number to 10.   I tested it with 1000 and it worked fine  100% of the time every time. at 10 Threads I tried 10,000 iterations here is the exact  text outputA(0).run( 99991 )A(1).run( 99992 )A(2).run( 99993 )A(3).run( 99994 )A(4).run( 99995 )A(5).run( 99996 )A(6).run( 99997 )A(7).run( 99998 )A(8).run( 99999 )A(9).run( 100000 )Main() Thread exited. Total Thread runs = 100000*/ // There are a few ways to do this and this is but one.// You could lever Thread.isAlive() for example.   // You could use a shared lock.//You could use 2  flag bits or booleans (One isn't enough)// I'll just use a shared lock.//   takes an argument of hhow many iterations// public class A implements Runnable{static int totalThreadRuns = 0;final static int MAX_A_THREADS = 10;volatile A aReference                  = null;volatile static Object masterLock = new Object();int id                                         = -1;static int totalIDs;Thread task         = null;  A(){   id = totalIDs++;} public void start(){   task = new Thread(this);   task.start();} public void stop(){   task = null;} public void run(){      // Force absolute execution serialization by hanging      // on to the masterLock.  (Monitor)      //   synchronized(masterLock)   {      totalThreadRuns++;      System.out.println("A("+id+").run( "+totalThreadRuns+" )");// Move the reference to simulate a bit of real work.      aReference = this;      masterLock.notifyAll();        }} public static void main(String args[]){Object waitObject = new Object();int y=0, z=0;int threadNum = A.MAX_A_THREADS;int loopCount = 1;A a[] = new A[threadNum ];      // Create the Threads      //System.out.println("Main() Thread creating threads");   try // done in a pinch argument processing   {      loopCount = Integer.parseInt(args[0]);      if(loopCount <1)         loopCount = 1;   }   catch(Exception any)   {      loopCount = 1;   }   for(z=0;z<threadNum;z++)   {      a[z] = new A();   }      // Run the Threads   System.out.println("Main() Thread running threads"+loopCount+" times");   for(y=0;y<loopCount;y++)   {      //      for(z=0;z<threadNum;z++)      {         a[z].start();      }          //      z--;  // rewind z to get very last reference           try      {         a[z].task.join(); //Wait for the last Thread                       }      catch(InterruptedException ie)         {         //---------      }   }   System.out.println("Main() Thread exited. Total Thread runs = "+totalThreadRuns);}}

.That's but one Method and there are others.
It shows how to use Thread.join(); to wait for a Thread to finish.
It works 100% of the time everytime.

(T)

 

Posts:2,909
Registered: 13.8.2003
Re: Synchronize problem...please help...  
Jun 21, 2004 2:02 AM (reply 17 of 46)



 
uh tswain, was that program supposed to deadlock without the notifyAll() ?
Notify has nothing to do with synchronized, only wait()***. I ran the above program without the notifyAll for 100000 iterations without any deadlocks.

I don't know where you have gotten the idea that you need notify when exiting synchronized blocks. (Or if I've gotten the wrong idea about what you're saying, then don't mind my blabbing).
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 21, 2004 11:28 AM (reply 18 of 46)



 
uh tswain, was that program supposed to deadlock
without the notifyAll() ?
Notify has nothing to do with synchronized, only
wait()***. I ran the above program without the
notifyAll for 100000 iterations without any deadlocks.

Thankfully you ran the working example. :)

That will not deadlock because the thread at once aborts after already
having released the monitor and therefore the next thread will always be able to
get the Monitor. No contention = no deadlock potential. This is because
it is doing almost nothing and executes very quickly. If it was running concurrently
then it would be a different story. To put it another way, by the time the
call to start() rolls around to the next Thread, the first Thread has already finished.
If the Thread took too much time to run the story could be different.

This was a bad example of that because I was just trying to answer
the original question which was "how have one Thread wait for another to finish
before continuing." Run the first example instead here:

////////////////// Example : save as ParentAndChild.java and compile

public class ParentAndChild implements Runnable
{
Thread task = null;
Child child = null;

ParentAndChild()
{
start();
}

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

public void stop()
{
child.task1 = null;
task = null;

}

public void run()
{
Thread controlThread = Thread.currentThread();
child = new Child();
child.start();
System.out.println("parent waiting for child");
while(!child.task1.isAlive())
{
synchronized(this)
{
try
{
wait(50);
}
catch(InterruptedException ie)
{
}
notifyAll();
}
}
System.out.println("Child is alive");
//---------------
while(controlThread == task)
{
synchronized(this)
{
try
{
wait(1000);
}
catch(InterruptedException ie)
{
}
notifyAll();
}
System.out.println("Parent");
}
}

public static void main(String args[])
{
ParentAndChild pac = new ParentAndChild();
try
{
pac.task.join();
}
catch(InterruptedException ie)
{
}
}

// Another yea old inner class

class Child implements Runnable
{
Thread task1 = null; //task1 avoids namespace conflict with parent
public void start()
{
task1=new Thread(this);
task1.start();
}

public void stop()
{
task1 = null;
}

public void run()
{
Thread controlThread1 = Thread.currentThread();
while(controlThread1 == task1)
{
synchronized(this)
{
try
{
wait(1000);
}
catch(InterruptedException ie)
{
}
}
System.out.println("Child");
}
}
}
}


////////////// end example


I don't know where you have gotten the idea that you
need notify when exiting synchronized blocks. (Or if
I've gotten the wrong idea about what you're saying,
then don't mind my blabbing).

If you are sharing the Monitor between 2 or more Threads,
then one will eventually be forced to wait because it cannot obtain the Monitor.
At that juncture, if you then didn't do a notify when the other Thread releases the Monitor,
then there is nothing to wake up the waiting Thread, and it will wiat forever.
This event is random and unpredictable, but inevitable.
I'll post more fun with Threads examples in the next few days. ATM I am getting flack for not getting
enough work done :/

(T)
 

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



 
If you are sharing the Monitor between 2 or more Threads, then one will eventually be forced to wait because it cannot obtain the Monitor.

Yes.

At that juncture, if you then didn't do a notify when the other Thread releases the Monitor, then there is nothing to wake up the waiting Thread, and it will wiat forever.

No.

Waiting for a monitor is not the same as calling the wait() method. In the former case once one thread releases the monitor another thread is automatically woken up. In the latter, you need to call notify().
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 22, 2004 8:08 AM (reply 20 of 46)



 
If you are sharing the Monitor between 2 or more
Threads, then one will eventually be forced to
wait because it cannot obtain the Monitor.

Yes.

At that juncture, if you then didn't do a notify
when the other Thread releases the Monitor, then there
is nothing to wake up the waiting Thread, and it will
wiat forever.

No.

Waiting for a monitor is not the same as calling the
wait() method.
Naturally there is a difference.
In the former case once one thread
releases the monitor another thread is automatically
woken up. In the latter, you need to call notify().

How do you interpret this then?
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Threads.doc.html#25549

When you synchronize you aquire the monitor which is akin to
"getting a lock" Now what does the JVM spec say about hainving the lock?

it says it

"does not relinquish ownership of it until a matching number of unlock operations have been performed."

I think that spells it out.

Well I gave you an example that proves it so I don't know what else to do to convince you :P

Show me and example of 2 threads that both call the same sychronized method
on some Object that doesn't eventually deadlock and I will believe you.
after all we could bandy words about for(;;)

(T)
 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 22, 2004 8:37 AM (reply 21 of 46)



 
it says it "does not relinquish ownership of it until a matching number of unlock operations have been performed."

What it does not say is that is the unlock operation has anything to do with the notify() methods. That's because it does not.

Please see section 18.3 (Locks and Synchronization)

A synchronized method automatically performs a lock operation when it is invoked; its body [...]. If execution of the method's body is ever completed, either normally or abruptly, an unlock operation is automatically performed on that same lock.
 

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



 
Show me and example of 2 threads that both call the
same sychronized method
on some Object that doesn't eventually deadlock and I
will believe you.
after all we could bandy words about for(;;)

As legosa points out, ending a sync block performs an unlock operation. Here's some sample code though:
public class NoDeadlock implements Runnable {    private final int id_;    private final Lock lock_;     public static void main(String[] args) {        int numThreads = Integer.parseInt(args[0]);        Lock lock = new Lock();        for (int ix = 0; ix < numThreads; ix++) {            Thread th = new Thread(new NoDeadlock(ix, lock));            th.start();        }    }     public NoDeadlock(int id, Lock lock) {        id_ = id;        lock_ = lock;    }     public void run() {        while (true) {            lock_.foo(id_);        }    }} class Lock {    public synchronized void foo(int ii) {        for (int ix = 0; ix < 100000; ix++) {            int j = ix % 2;        }        System.out.println(hashCode() + " " + ii);    }}
Run it with one arg--the number of threads.
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 22, 2004 10:37 AM (reply 23 of 46)



 
it says it "does not relinquish ownership of it
until a matching number of unlock operations have been
performed."

What it does not say is that is the unlock
operation has anything to do with the notify()
methods. That's because it does not.

You mean you think it does not :P

Please see section 18.3 (Locks and Synchronization)

A synchronized method automatically performs a lock
operation when it is invoked; its body [...]. If
execution of the method's body is ever completed,
either normally or abruptly, an unlock operation is
automatically performed on that same lock.

That pertains to locks but not to wait sets.

Read further in the spec. (note It says lock not wait and we know this is done by the synch statement)

" Suppose that thread T has in fact performed N lock operations
on the object that have not been matched by unlock operations
on that same object. "

I admit it doesn't say it adds it automatically.

All speculation aside here is what I know from testing it myself.
If I make some Threads that call a synchronized method without notifying, it will deadlock.
Why? I don't think saying it is non standard is a proper answer.

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
repudiation :)

I always try to prove everything with code so I am not going to accept
what you say without a demonstrative example that proves you are correct.
Thus far every test I have ever tried has led me to the conclusion that I have.
I didn't come to this idea out of the ether, but after alot of testing so
post some code that proves me wrong :)

(T)

 

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



 
Please see section 18.3 (Locks and Synchronization)

A synchronized method automatically performs a lock
operation when it is invoked; its body [...]. If
execution of the method's body is ever completed,
either normally or abruptly, an unlock operation is
automatically performed on that same lock.

That pertains to locks but not to wait sets.

Where does it say that synchronizing has anything to do with wait sets? You must call notify or notifyAll if some other thread has called wait. If no other thread has called wait, it is not necessesary to call notify. Simply exiting the sync block releases the lock and lets the next thread obtain it.

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
it proven to me and print a full public
repudiation :)

I did. It's not possible to prove via testing that it will never deadlock, but I went to about 5 million iterations on two threads with no deadlock, a little over a million on 3 threads, and am currently in the neighborhood of 200,000 with 100 threads.
 

Posts:334
Registered: 5/23/97
Re: Synchronize problem...please help...  
Jun 22, 2004 11:23 AM (reply 25 of 46)



 
Please see section 18.3 (Locks and

Where does it say that synchronizing has anything to
do with wait sets? You must call notify or notifyAll

if some other thread has called wait. If no other
thread has called wait, it is not necessesary to call
notify. Simply exiting the sync block releases the
lock and lets the next thread obtain it.

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
it proven to me and print a full public
repudiation :)

I did.

It's not possible to prove via testing that it
will never deadlock,

If it can, then it will.

but I went to about 5 million
iterations on two threads with no deadlock, a little
over a million on 3 threads, and am currently in the
neighborhood of 200,000 with 100 threads.

Oh I see

class MyClass {
private Thread thread
public synchronized void doIt(String dummy)
{
if (thread != null && thread.isAlive()) {
return;
}
else {
thread = new Thread(this);
thread.start();
}
}
// ...
}

I this example you are making a new Thread every time, there is no run method and
the thread doesn't do anything; it will probably abort right away.

This is a fundamental difference.
Is the call to doIt called from a single Thread context?

Make 2 Threads that never end and call a synchronized method over and over.
Use Runnable and not Thread to do this.

Here are the facts.

1- The original example without a notify always deadlocks.
2- The original example with a notify doesn't.
Why is that so? I think saying it is not standard is not a valid explanation.

(T)


 

Posts:1,183
Registered: 1/23/02
Re: Synchronize problem...please help...  
Jun 22, 2004 11:30 AM (reply 26 of 46)



 
I this example you are making a new Thread every time, there is no run method and the thread doesn't do anything; it will probably abort right away.

That code was response to OP's question, not part of the discussion about deadlocks. See jverd's code in reply #22, which is his response to your deadlock challenge.
 

Posts:6,750
Registered: 1/25/04
Re: Synchronize problem...please help...  
Jun 22, 2004 11:39 AM (reply 27 of 46)



 
It's not possible to prove via testing that it
will never deadlock,

If it can, then it will.

Given an infinite amount of time, yes. So, if you run a test program for infinitely long and it doesn't deadlock, then you have proven that it cannot deadlock. However, that is not possible. Given a non-zero probability of not deadlocking, no matter how long you run a program (for a finite period) without deadlocking, you cannot prove that deadlocking is impossible. All you can prove is that the longer it runs without deadlocking, the less likely a deadlock is, until at some point you can decide you are "sure enough."
 

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



 
class MyClass {
private Thread thread
public synchronized void doIt(String dummy)
{
if (thread != null && thread.isAlive()) {
return;
}
else {
thread = new Thread(this);
thread.start();
}
}
// ...
}

I this example you are making a new Thread every time,
there is no run method and
the thread doesn't do anything; it will probably abort
right away.

Yeah, no run method. I'm still not sure why it deadlocks, but this example is useless because no real code would every be written like that.

The JLS makes it clear that you need notify if and only if you use wait(). You asked for code with multiple threads syncing on the same object that doesn't deadlock, and I gave it to you. Now you provide a ridiculous an incomplete example that's supposed to demonstrate that you need to call notify even without wait()? It doesn't demonstrate that.


This is a fundamental difference.
Is the call to doIt called from a single Thread
context?

What do you mean here? If you have a point, please make it.

Make 2 Threads that never end and call a synchronized
method over and over.
Use Runnable and not Thread to do this.

I did. See the sample code I posted.

Here are the facts.

1- The original example without a notify always
deadlocks.
2- The original example with a notify doesn't.
Why is that so? I think saying it is not standard is
not a valid explanation.

In this case it is. To show that you can get bad behavior with threads that are used in a way you're not supposed to use them, and that do absolutely nothing doesn't really demonstrate anything.

Can you provide code where your Runnable or Thread has a run method, synchronizes as you described, doesn't call wait, and deadlocks?
 

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



 
Oh, I thought the code tswain posted was his way of demonstrating that you do need to call notify even without wait().
 
This topic has 46 replies on 4 pages.    « Previous | 1 | 2 | 3 | 4 | Next »