Java volatile objects in 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) "Qs" items from N threads at the same time?
"WorksWaiting" is for synchronization between the controller thread (1 or 2) and the monitored thread (N), while N controls the read / write in the queue at the same time.
Deleting / creating a queue will be done from the controller threads.
Thank.
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.
source to share
Is it safe to read / write (not destroy, not create) "Qs" items from N threads at the same time?
Not. Is not.
See the following situation.
Thread 1 Thread 2
qs.add(queue1); qs.delete(queue1);
... ...
qs.add(queue100); qs.delete(queue100);
You add and remove objects at the same time to unsynchronized List
.
If we assume that you both are trying to remove and add to the list object, you will get a ConcurrentModificationException because yours has List
not been synchronized and the threads will try to work on the same object. It doesn't matter which object you store in List<queue>
, because this list is an external object and it is not synchronized.
But. Your queue class is save-thread for the following 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 work.
Therefore, if you want to synchronize elements in
List
, you need to create a class that extends from
List
and synchronize methods
add()
and
delete()
.
source to share
As long as the referee in the queue doesn't change (i.e. you don't create and use a new queue at runtime), it shouldn't be mutable (it doesn't matter). Likewise, if the reference to the list within the queue does not change (i.e. you do not create or use a new list at runtime), the list should not be mutable (this also does not matter)
What matters is that a list is a thread-safe implementation, whose internal variables are volatile and whose code syncs as needed, etc., because the references to them are stored (to work objects) and its internal elements, which are will be mutated and these changes should be visible for all streams (volatile).
Your code doesn't matter - it's a list that needs to be thread safe.
source to share