0

I want to update a Object in another thread, and then access it in current thread:

 public Object getValueAt(final int rowIndex, int columnIndex) {
            data.getRealm().exec(new Runnable(){
                @Override
                public  void run() {

                    System.out.println("Object at " + rowIndex  + " in WritableList is "  + data.get(rowIndex));
                    object = (DOModel) data.get(rowIndex);
                    System.out.println(object);
                    object.notify();
                }
            });
// suspend current thread
            try {
                synchronized (object){
                    object.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(columnIndex == 0){
                System.out.println(object);
                return object.getId();
            }
    }

but when I run my code a java.lang.IllegalMonitorStateException occurs.

I changed my code, see comments in code: Edit --------------------------------

    public Object getValueAt(final int rowIndex, int columnIndex) {
            data.getRealm().exec(new Runnable(){
                @Override
                public  void run() {
                    System.out.println("Object at " + rowIndex  + " in WritableList is "  + data.get(rowIndex));
                    object = (DOModel) data.get(rowIndex);
                    synchronized(object){
                        object.notify();
                    }
                }
            });
            try {
                synchronized (object){
                    object.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
// this line below is never executed.
                System.out.println(object);
            if(columnIndex == 0){

                return object.getId();
            }
    }
CaiNiaoCoder
  • 3,269
  • 9
  • 52
  • 82
  • possible duplicate of [Java Wait and Notify: IllegalMonitorStateException](http://stackoverflow.com/questions/7126550/java-wait-and-notify-illegalmonitorstateexception) – assylias Mar 28 '12 at 15:00

2 Answers2

4

To be able to notify, you need to be synchronized on the monitor. You will need to do:

synchronized (object) {
   object.notify();
}

Instead of the unsynchronized notify() in run().

You are going to run into race-conditions any way. Your main thread could be trying to synchronize on object when it hasn't been retrieved yet in the separate thread.

Better would be to define a separate lock/monitor and use that for synchronisation and notification.

Second Edit: Also: If the separate thread retrieves the object and notifies before your main thread waits, it could be waiting indefinitely.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • I already gave you all the pieces you need. Other than that, read the [Concurrency Tutorial](http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html), specifically the 'Guarded Block' section, but don't skip the preceding sections! – Mark Rotteveel Mar 29 '12 at 18:54
1

notify() call should be within the synchronized block of same monitor

Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94