2012-08-05 35 views
0

以下是我的Java代码的主要操作之一:是在arraylist/atomic double array(Google Guava)线程安全的.get()操作?

AtomicDoubleArray array1 = new AtomicDoubleArray(25); 

for(int i =0 ; i< array1.size(); i++){ 
    double a = array1.get(i)*0.001; 
    double b = a+ array1.get(i); 
    array1.set(b); 
} 

是上面的代码是线程安全的?如果没有,我可以让上面的代码线程安全吗?我不想在读取元素时保持锁定,而是在设置每个组件的值时锁定它。这意味着多个线程可以设置array1的不同组件。

+1

这不会编译 – SLaks 2012-08-05 12:45:51

+0

什么是“原子DoubleArray array1 =新的原子DoubleArray(25);”?我们怎么能说这个类(可能是你自己的)是线程安全的? – 2012-08-05 12:51:04

+0

它是一个番石榴类:[AtomicDoubleArray](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/AtomicDoubleArray.html) – 2012-08-05 12:52:57

回答

3

上述代码是线程安全的吗?

这取决于你的意思与线程安全。每个单独的get()和set()操作都应该是线程安全的,但多个线程可能同时调用此方法,因此在第一个线程完成迭代之前,单个数组条目可能会被第二个线程重新分配。没有什么可以做,除了在一个共同的对象同步(其可以为数组或其他一些专用锁对象)

我想不会保持在阅读元素,但设定值时锁定 锁定。这意味着线程的数字 可以设置array1的不同组件。

如果我没有理解这个权利,你可以用你的代码,是不需要额外的锁定(见上文),除了这部分:

array1.set(b); 

这需要阅读:

array1.set(i, b); 
+0

**多个线程可能同时调用此方法,因此在第一个线程完成迭代之前,可以通过第二个线程重新分配单个数组条目。**这对我来说不是问题。唯一的问题是,当sum线程正在读取值时,可能会被另一个线程修改,并且该值可能不会被读取该值的线程看到,并且最终返回** NaN ** – thetna 2012-08-05 15:46:39

1

连续两次调用array1.get(i)时,可能会得到不同的值。如果你想避免同步,看看复制写数据结构(例如CopyOnWriteArrayList - http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

+0

它不会重要的是如果我在连续调用中得到两个不同的值。但它返回null,这最终导致NaN – thetna 2012-08-05 15:42:28

+1

你是说array1.get(i)返回null作为另一个线程并发修改array1的副作用? – 2012-08-07 12:16:56

+0

是的,这是我的全部观点:) – thetna 2012-08-07 15:31:03