2012-03-28 49 views
0

我想更新在另一个线程一个对象,然后访问它在当前线程:Java线程,这有什么错我的代码

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

但是当我运行我的代码发生java.lang.IllegalMonitorStateException。

我更改了我的代码,请参阅代码中的注释: 编辑--------------------------------

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

可能重复的[爪哇Wait和通知:抛出:IllegalMonitorStateException](http://stackoverflow.com/questions/7126550/java-wait-and-notify- illegalmonitorstateexception) – assylias 2012-03-28 15:00:20

回答

4

为了能够通知,您需要在显示器上进行同步。您需要执行以下操作:

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

而不是run()中的未同步notify()。

您将以任何方式遇到种族条件。当您的主线程尚未在单独的线程中检索时,可能会尝试在object上同步。

更好的办法是定义一个单独的锁定/监视器并将其用于同步和通知。

第二编辑: 另外:如果单独的线程检索对象并在主线程等待之前通知它,它可能会无限期地等待。

+0

你能告诉我如何做我想在我的代码中做什么? – CaiNiaoCoder 2012-03-29 13:06:33

+0

我已经给你所有你需要的作品。除此之外,请阅读[并发教程](http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html),特别是'保护区块'部分,但不要跳过前面的章节! – 2012-03-29 18:54:38

1

notify()呼叫应该是相同监视器的同步块内