3
// 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?

"WorksWaiting" is meant to synchronize between controller thread(1 or 2) and a controlled thread (N) while N controlleds reading/writing to Queues concurrently.

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.
5
  • Neither WorksWaiting nor Qs have been initialized, so it's unclear if a thread-safe list implementation is used there. Apart from that: Variable names should be lower case in java. And Queueue should probably be Queue instead. Commented Nov 27, 2014 at 22:21
  • Its just java's own list, not my implementation. Commented Nov 27, 2014 at 22:23
  • List is just an interface, not an implementation. What concrete implementation are you assigning to worksWaiting and qs? Commented Nov 27, 2014 at 22:24
  • Just a class having some arrays and strings, nothing more. Im meaning the pieceofwork part. Commented Nov 27, 2014 at 22:24
  • 1
    One more try: In your code, qs is null as you've not assigned anything to it yet. Somewhere in your code you must create a new list instance and assign it to qs via qs = new .... So what kind of object do you create there? Commented Nov 27, 2014 at 22:28

3 Answers 3

3

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

Your code is irrelevant - it's the list that needs to be threadsafe.

Sign up to request clarification or add additional context in comments.

Comments

2

Objects are not volatile. Variables are volatile. It is safe to play with the variable 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.

2 Comments

Do you mean i can change the class instance itself(workswaiting) but not its individual fields(strings, arrays, etc...)? So volatileness is not passed to fields? Do I need synchronized(this){...} in its referring thread??
You can change the variable, i.e. set it to null or to a different object, and this will be seen correctly by all threads if it's declared volatile. You need to syncrhonize access to the object if it isn't thread-safe, as I stated.
1

Is it safe to read/write(not destroy, not create) elements of "Qs" from N threads at the same time?

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.

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. Doesn't matter which object you store in List<queue> because this list is outer object and he non-synchronized.

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.

2 Comments

Do you mean it is better to use only a single List (not nested) and make its elements("pieceofwork") volatile instead?
I am anticipating your question :) Look for an updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.