Logo 
Search:

Java Forum

Ask Question   UnAnswered
Home » Forum » Java       RSS Feeds

A challenging question about Threads&Synchronization

  Asked By: Bastet    Date: Jan 22    Category: Java    Views: 1108
  

that is challenging question about
threads&synchronization..I write the code below while
trying to watch the stuff related with sync&threads.
and observe that if i comment out the t.start(), the
t.waitTest() method is not waiting forever and does
not cause a deadlock that is supposed to be until a
notify or notifyAll() is called. it immediately runs
and program ends. however t.start() method doesn't do
anything about synchronization. Does anyone know the
answer??..Just run the both cases to see!!!?.

Note: java version is=Java(TM) 2 Runtime Environment,
Standard Edition (build 1.4.2-b28).


/*
* Test.java
*
* Created on May 6, 2004, 3:47 AM
*/

/**
*
* @author tansel
* @version
*/




class ThreadTest extends Thread {

public synchronized void notifyTest(){
System.out.println("notify will be
called...");
try{
Thread.sleep(10000);
notify();
System.out.println("notify has
called...");
Thread.sleep(10000);
}catch(Exception ex){ex.printStackTrace();}


}

public synchronized void waitTest(){
try{
wait();
System.out.println("wait has called..");
}catch(Exception ex){
ex.printStackTrace();
}

}


public void run(){
// notifyTest();
}


}

public class Test{
public static void main(String arg[]){
ThreadTest t=new ThreadTest();
//t.start(); //comment out t.start()routine,will
//change the case.WHY??

t.waitTest();

}

}

Share: 

 

6 Answers Found

 
Answer #1    Answered By: Herbert Weaver     Answered On: Jan 22

it think that u won't have a real thread context at operating system level
without a start  system call.

 
Answer #2    Answered By: Richie Smith     Answered On: Jan 22

You're actually just misusing a Thread. A thread cannot notify itself to wake
up from a wait. I think you had better take a look at whatever example you were
using because I'm certain it's not written like the code  you have here. If one
thread is told to wait, it will wait until notified. Which means that it will
*not* execute any more code. Another thread has to perform the notify in order
to wake that thread up.

 
Answer #3    Answered By: Emma Brown     Answered On: Jan 22

In my opinion, it is another argument to discuss whether it could be
used such or not.. the problem here is different..language says wait
method should release the lock and get in a wait state until it is
notified. Java should provide for me.

also i can give an example to the usage of such self waiting and wake
up..think a thread is performing I/O and get blocked. think a method
getData() provide the data after I/O completion. an such a design can
be implement..

class IOThread(){
String data;
.
.
public synchronized getData(){
wait();
return data;
}
public synchronized void notfiyData(){
notify();//data is ready
}

public void run(){
do I/O get Data;
notfiyData();
}

Note: Another point, i am actually using the posted code  like
implementation to create a suspend method  in J2ME. so it is a must
for me.

 
Answer #4    Answered By: Willie Gomez     Answered On: Jan 22

Let me spell this out for you. This is taken straight from the javadocs on
Sun's website under the Object class for the definition of the wait method:

"Causes current thread to wait until another thread invokes the notify() method
or the notifyAll() method  for this object. In other words, this method behaves
exactly as if it simply performs the call wait(0). "

Read the first sentence carefully. Now let's look at your program  again:

class ThreadTest extends Thread {
public synchronized void notifyTest(){
System.out.println("notify will be called...");
try{
Thread.sleep(10000);
notify();
System.out.println("notify has called...");
Thread.sleep(10000);
}catch(Exception ex){ex.printStackTrace();}
}
public synchronized void waitTest(){
try{
wait();
System.out.println("wait has called..");
}catch(Exception ex){
ex.printStackTrace();
}
}
public void run(){
notifyTest();
}
public static void main(String arg[]){
ThreadTest t=new ThreadTest();
t.start();
t.waitTest();
}
}

I modified this slightly to save space. There are two threads I see running
here. There's the main thread which is started by the JVM and the thread class
that you create. Your thread will never run  if you never call the start  method.
So when you call waitTest, the only thread you are telling to wait is the main
JVM thread. That thread will then wait indefinitely because there is no other
thread that can notify it to stop.

However, if you start your own thread, you will first enter a sleep. Here is
what is written in the javadoc for Thread.sleep method:

"Causes the currently executing thread to sleep (temporarily cease execution)
for the specified number of milliseconds. The thread does not lose ownership of
any monitors."

What's important here is that second sentence. The thread has ceased execution
but it has not let go of that synchronized method so that some other thread can
call it. And, btw, you should not be using synchronized here because it does
not make any sense. You only synchronize on code  that you want to protect from
having several threads using it all at the same time.

The next thing that happens is you call notify. But it's wasted because no
thread is waiting. Then you go straight to the next sleep. Once the thread
exits the synchronized method notifyTest, the main thread is given permission to
do operations on your thread. It was not allowed to call any methods on your
thread before because of the synchronized lock you have on the notifyTest
method. If you put a println in between the start method call and the waitTest
method call you'll see that the main thread still runs even after your thread
has started but is not allowed to continue because the thread has been locked.

It is not an argument whether or not a thread can be used in this way because it
can't do the things you're trying to make it do. A thread can not tell itself
to wait and then later magically call notify itself to wake itself up. Another
thread has to call notify on the same synchronized code that the waiting thread
is waiting at. If you can produce an example of a thread that can tell itself
to wait and then later notify itself to wake up, then please do. The IO example
you provided doesn't make any sense.

 
Answer #5    Answered By: Pravat Jainukul     Answered On: Jan 22

But your explanation about the code,does not clear the main
problem comes to my mind. so i simplify the code  and i slip out the
codes nonsense not to discuss unrelated things. So my question  is
simple,

1-Why is the method  waitTest not waiting forever?..
2-Why is the method waitTest waiting forever if t.start() is
commented as it should be.

the real problem is question 1..in my opinion in both cases with
commented and without commented waitTest should wait forever.

Another point: Could you create a thread design that works in J2ME
MIDP1.0 or 2.0 profile that has a suspend method in it. currently
suspend is not included but you should able to build a thread class
that can suspend itself and resume itself. how can you do such a
thing without self notify&wake up .


class ThreadTest extends Thread {

public synchronized void waitTest(){
try{
wait();
System.out.println("waitTest has called..");
}catch(Exception ex){
ex.printStackTrace();
}

}
public void run(){
System.out.println("I'M DOING NOTHING& I'M NONSENSE :(");
}
}

public class Test{
public static void main(String arg[]){
ThreadTest t=new ThreadTest();
t.start(); // t.waitTest() never waits..
t.waitTest();

}

}

 
Answer #6    Answered By: Rocco Anderson     Answered On: Jan 22

1. Your program  does not wait forever in this case because you are telling your
ThreadTest thread to wait. The main JVM thread is not waiting and once that
finishes, the program finishes, no matter what your ThreadTest thread is doing.
2. Your program waits forever in this case because you are telling the main JVM
thread to wait and nothing ever notifies it to wake up and finish. I explained
this in the previous email; I quote myself:

"There's the main thread which is started by the JVM and the thread class that
you create. Your thread will never run  if you never call the start  method. So
when you call waitTest, the only thread you are telling to wait is the main JVM
thread. That thread will then wait indefinitely because there is no other
thread that can notify it to stop."

I answered both of your questions in the previous email. I suppose you didn't
read it. And as to your question  about having a thread suspend itself, yes that
is possible, but not in the way that you think. But I will tell you that you're
going to have a really difficult time using threads if you don't understand how
they work.

 
Didn't find what you were looking for? Find more on A challenging question about Threads&Synchronization Or get search suggestion and latest updates.