2011-08-07 104 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