CaiNiaoCoder
CaiNiaoCoder

Reputation: 3319

java threading, what's wrong with my code

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();
            }
    }

Upvotes: 0

Views: 103

Answers (2)

Mark Rotteveel
Mark Rotteveel

Reputation: 109253

To be able to notify, you need to be synchronized on the monitor. Instead of the unsynchronized notify() in run(), you will need to do:

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

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.

Also, if the separate thread retrieves the object and notifies before your main thread waits, it could be waiting indefinitely.

Upvotes: 4

Prince John Wesley
Prince John Wesley

Reputation: 63708

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

Upvotes: 1

Related Questions