views:

72

answers:

4

Hi, I have a method and a thread which I'd like to run in the following order: First the method should do something with an object, and then the thread should do something with the object. They share the same object. I have to synchronize them, but I am just meeting with Threads. How can I do that?

private synchronized method()
{
//do something with an object (a field)
}

Runnable ObjectUpdater = new Runnable()
{
//do something with the object after the method has finished 
} 

My code, that somehow manages to freeze my Main thread (where the method is) My thread code:

private Runnable something = new Runnable(){
synchronized (this){
while (flag == false)
{ try {wait();)
catch (IntExc ie) {e.printStackTrace...}
}
//here it does its thing
}
setFlag(false);
}
My method code (part of the main thread)
private void Method()
{
//do its thing
setFlag(true); 
notifyAll();
}
+1  A: 

Apart from synchronizing on the object, you could call the method as first statement in the new thread, or you could start the new thread at the end of the method.

It is hard to say what is the best approach in your case, maybe you can give us some more details on the how and what?

Update

In answer to your code (for some reason I cannot add another comment...)

Is the method called from a synchronized(this) block? If not the notifyAll() should be in a synchronized block. Also, can you update the code to show where/how your main thread interacts with the method and the object?

rsp
I have a thread that updates a UI component. And I also have the main thread. The main thread initializes stuff, which the UI component relies on. In order to be drawn properly, the stuff must be initialized before the UI component gets drawn. Also, the main thread, the object and the separate thread are not in the same class.
George
@George, the main thread could call the method to update the object before it makes it known to the UI thread. If that is not possible, synchronize on the object and introduce a method like `isInitialised()` so that the UI thread can check that the object is in the correct state after it aquired the lock.
rsp
Thanks, that is what I am trying to do for the better part of an hour. I made a flag, and the UI update thread waits "for the green light" by the following codewhile (theNameOfMyFlag()==false){try {wait} catch ....}//after this block, do what it should doand in my main thread - theNameOfMyFlag.set(true);notifyAll();Log.d....Problem is typical - IlligalMonitorStateException, as the object is not locked before "wait()". If I lock the object through synchronized (this) or ReentrantLock my application freezes. Something's wrong...
George
@George, the whole block of code should be in a `synchronized(object)` block and then wait using `object.wait()` (using a timeout) what you experience is probably a deadlock caused by 2 threads waiting for the other to free a lock (th1: got this.lock, wait for object.lock, th2: got object.lock, wait for this.lock) if you post the code you have so far, maybe we can see whats causing the deadlock.
rsp
@rsp, I have posted the code, thank you in advance for any further help you can provide.
George
+1  A: 

To me that is simple questions

" you said that I do not know which is going to access the object first - the separate ObjectUpdater thread, or the main thread (with the method). If the separate thread accesses it before the main thread, that is bad and I don't want this to happen"

if you want the main thread method to call first then the objectUpdater thread , have a flag to know whether the method is visited first by main thread ,if it is updater then call wait to this thread , once main finishes it call notify which will run separator thread, to know which thread is main thread or updater thread , set a name to the thread while creating it. and get the name as Thread.currentThread().getName().

Suresh S
A: 

I think better approach would be to call the method using which you want to perform something with an object, and then declare the thread which would do something with an object.

JVM
A: 

Use the Semaphore class to allow access to the object.

public class Main
{
  public static void main (String[] args) {
    final Obj obj = new Obj();
    final Semaphore semaphore = new Semaphore(0);
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
      semaphore.acquire();
    } catch (InterruptedException ex) {
      Thread.currentThread().interrupt();
      return;
    }
    obj.doSomething();
      }
    });
    t.setName("test");
    t.start();

    try {
      Thread.sleep(1000);
    } catch (InterruptedException ignored) {
    }
    obj.doSomething();
    semaphore.release();
  }
}

class Obj {

  public void doSomething() {
    System.out.println("something done by " + Thread.currentThread());
  }
}
Carlos Heuberger