非易失性对象中的java volatile对象

时间:2014-11-27 22:15:44

标签: java list concurrency

// structure is like this, but not exact formation.
class queue
{
    volatile List<pieceOfWork> worksWaiting;
}

List<queue> qs; //  pieceOfWork has only some primitive arrays and strings.

同时从N个线程读取/写入(不破坏,不创建)“Qs”元素是否安全?

“WorksWaiting”用于在控制器线程(1或2)和受控线程(N)之间进行同步,而N控制同时读取/写入队列。

队列的删除/创建将由控制器线程构成。

谢谢你。

 th read   th write 
(cpu sse) (gpu opencl executor)
 ^         ^
 |         |
 W W W W W W  ....w<--- controller thread adding new works to queue and
                                                  deleting finished ones.
                                               also splits a work item if 
                                             it is not finished in short time.

3 个答案:

答案 0 :(得分:3)

只要 referece 到队列没有改变(即你在执行期间没有创建和使用新队列),它就不必是volatile(它没有区别) )。同样,如果对队列内部列表的引用没有改变(即你在执行期间没有创建和使用新列表),那么列表不必是易失性的(它也没有区别)

重要的是列表是线程安全的实现 - 其内部变量是易失性的,其代码根据需要同步等,因为它是列表的引用保持(对工作对象)及其内部将发生变异,这些变化需要对所有线程都可见(易变)。

您的代码无关紧要 - 列表需要线程安全。

答案 1 :(得分:2)

对象不易变形。 变量是易变的。使用变量worksWaiting是安全的。使用它引用的对象是不安全的,除非它被记录为线程安全或您正确同步对它的所有访问。

答案 2 :(得分:1)

  

读/写(不破坏,不创建)&#34; Qs&#34;的元素是否安全?来自N个线程同时?

没有。不是。

见下一个情况。

Thread 1                Thread 2

qs.add(queue1);      qs.delete(queue1); 
...                  ...
qs.add(queue100);    qs.delete(queue100);

您同时添加并删除对象非同步 List

如果我们假设您都尝试删除并添加到列表对象,则会得到ConcurrentModificationException,因为您的List未同步,并且线程将尝试使用相同的对象。与List<queue>中存储的对象无关,因为此列表是外部对象,而非同步。

但是。您的队列类是保存线程到下一种情况:

queue qs = new queue();

Thread 1                                   Thread 2

qs.worksWaiting.add(pieceOfWork1);      qs.worksWaiting.delete(pieceOfWork1); 
...                                     ...
qs.worksWaiting.add(pieceOfWork100);    qs.worksWaiting.delete(pieceOfWork100);

在这种情况下,同步将起作用。

<小时/> 因此,如果您想在List中使用synch元素,则需要创建一个从List扩展并同步add()delete()方法的类。