2011-08-07 75 views
2

A是AbstractCollection的一個子類。java多線程編程內存一致性問題

final A a = new A(); 
... //Add some objects into a 

ExecutorService es = Executors.newFixedThreadPool(1); 
Future f1 = es.submit(new Callable<B>() { 
    public B call() { 
     ... //Modify the objects in a 
     return B; 
    } 
}); 
f1.get(); 
... //Read a 

現在的問題是,當我讀了一個,修改不存在。根據java文檔:「異步計算所採取的動作發生在跟在另一個線程中對應的Future.get()之後的動作之前」。所以我想知道爲什麼會出現這種不一致。任何幫助深表感謝。

+0

這是基本的併發性。也許你應該花一些時間閱讀[Lesson:Concurrency](http://download.oracle.com/javase/tutorial/essential/concurrency/index.html)教程。 – mre

+0

我剛剛發現可能發生的事情。我在Eclipse IDE中使用調試來檢查變量「a」,其中發現「a」未被修改。但是,當我在不使用調試的情況下打印出「a」的值時,可以看到修改。也許我不應該使用調試多線程編程? – took

+0

調試器有時可能會出現變量值等顯示問題,最好在您的代碼中進行大量日誌記錄並查看輸出。 – pstanton

回答

2

我重新寫你的例子有一些標準的對象,它似乎很好地工作:

public static void main(String[] args) throws Throwable 
{ 
    final StringBuffer a = new StringBuffer(); 
    a.append("a"); 

    ExecutorService es = Executors.newFixedThreadPool(1); 
    Future<String> f1 = es.submit(new Callable<String>() 
    { 
     @Override 
     public String call() 
     { 
      a.append("b"); 
      return "done"; 
     } 
    }); 

    f1.get(); 
    System.out.println(a.toString()); 
    es.shutdownNow(); 
} 

如果您使用的是良好的IDE你總是可以斷點的代碼在行動中看到的併發行爲。

也許你的問題在你的A類中。

+0

也可以通過Thread.currentThread()。getName()來記錄線程名稱, – pstanton