简体   繁体   English

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

[英]java volatile objects in non volatile objects

// 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.

Is it safe to read/write(not destroy, not create) elements of "Qs" from N threads at the same time? 从N个线程同时读/写(不破坏,不创建)“Qs”元素是否安全?

"WorksWaiting" is meant to synchronize between controller thread(1 or 2) and a controlled thread (N) while N controlleds reading/writing to Queues concurrently. “WorksWaiting”用于在控制器线程(1或2)和受控线程(N)之间同步,而N控制同时读取/写入队列。

Deletion/creation of queue will be made of controller threads. 删除/创建队列将由控制器线程组成。

Thanks you. 谢谢。

 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.

As long as the referece to queue doesn't change (ie you don't create and use a new queue during execution), it doesn't have to be volatile (it makes no difference). 只要referece到队列不会改变(即你没有创建和执行过程中使用新的队列),它并没有挥发(没有区别)。 Likewise, if the reference to the list inside queue doesn't change (ie you don't create and use a new list during execution) the list doesn't have to be volatile (it also makes no difference) 同样,如果对队列内部列表的引用没有改变(即你在执行期间没有创建和使用新列表),那么列表不必是易失性的(它也没有区别)

What does matter is that the list is a threadsafe implementation - whose internal variables are volatile and whose code is synchronised as required etc, because it's the references the list is holding (to the work objects) and its internals that will be mutated and these changes need to be visible to all threads (volatile). 什么事情的是,该清单是线程安全的实现-它的内部变量是挥发性的,其代码是同步的要求等,因为它是名单持有(该工作对象)的引用和其内部将被突变而这些变化需要对所有线程可见(volatile)。

Your code is irrelevant - it's the list that needs to be threadsafe. 你的代码是无关紧要的 - 它是需要线程安全的列表

Objects are not volatile. 对象不易变形。 Variables are volatile. 变量是不稳定的。 It is safe to play with the variable worksWaiting . 使用变量worksWaiting是安全的。 It is not safe to play with the object it refers to unless it is documented as thread-safe or you synchronize all access to it correctly. 使用它引用的对象是不安全的,除非它被记录为线程安全或您正确同步对它的所有访问。

Is it safe to read/write(not destroy, not create) elements of "Qs" from N threads at the same time? 从N个线程同时读/写(不破坏,不创建)“Qs”元素是否安全?

No. Is not. 不,不是。

See the next situation. 看下一个情况。

Thread 1                Thread 2

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

You add concurrently and delete objects to non-synchronized List . 您同时添加并删除对象到非同步 List

If we assume that you both try to remove and add to the list object, you get ConcurrentModificationException because your List was not synchronized and threads will be try to work with same object. 如果我们假设您都尝试删除并添加到列表对象,则会得到ConcurrentModificationException,因为您的List未同步,并且线程将尝试使用相同的对象。 Doesn't matter which object you store in List<queue> because this list is outer object and he non-synchronized. 无关您在List<queue>存储哪个对象,因为此列表是外部对象而且是非同步的。

But. 但。 Your queue class is save-thread to the next situation : 您的队列类是保存线程到下一个情况:

queue qs = new queue();

and

Thread 1                                   Thread 2

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

And in this situation synchronization will works. 在这种情况下,同步将起作用。


So if you want synch elements in your List you need to create a class which extends from List and synchronize add() and delete() methods. 因此,如果您想在List synch元素,则需要创建一个从List扩展并同步add()delete()方法的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM