views:

81

answers:

4

I have a simple bean @Entity Message.java that has some normal properties. The life-cycle of that object is as follows

Instantiation of Message happens on Thread A, which is then enqueued into a blockingQueue

Another thread from a pool obtains that object and do some stuff with it and changes the state of Message, after that, the object enters again into the blockingQueue. This step is repeated until a condition makes it stop. Each time the object gets read/write is potentially from a different thread, but with the guarantee that only one thread at a time will be reading/writing to it.

Given that circumstances, do I need to synchronize the getters/setters ? Perhaps make the properties volatile ? or can I just leave without synchronization ?

Thanks and hope I could clarify what I am having here.

+2  A: 

If you're sure that only one thread at a time will access your object, then you don't need synchronisation.

However, you can ensure that by using the synchronized keyword: each time you want to access this object and be sure that no other thread is using the same instance, wrap you code in a synchronized block:

Message myMessage = // ...
synchronized (myMessage) {
    // You're the only one to have access to this instance, do what you want
}

The synchronized block will acquire an implicit lock on the myMessage object. So, no other synchronized block will have access to the same instance until you leave this block.

Vivien Barousse
Synchronizing individual getters and setters doesn't really prove anything if two threads were to actually interleave on the object. They'll still see it in inconsistent states/do partial overwrites. This answer is the better way to address the problem.
Affe
@Vivien_Barousse so, I do not actually need to synchronize anything because there won't be accessed concurrently. This answers my question, thank you !
David Hofmann
A: 

You don't need to do synchronization yourself, because the queue does it for you already.

Visibility is also guaranteed.

irreputable
A: 

It would sound like you could leave of the synchronized off the methods. The synchronized simply locks the object to allow only a single thread to access it. You've already handled that with the blocking queue.

Volatile would be good to use, as that would ensure that each thread has the latest version, instead of a thread local cache value.

tylermac
Using `volatile` with a `BlockingQueue` is unnecessary (and an inefficient duplication of effort); part of the `BlockingQueue` contract is that any actions by a thread prior to enqueue-ing an object "happen-before" the object is dequeued by another thread.
erickson
Good to know. I knew volatile was needed when another thread changes the value of a field. It makes sense that blocking thread would care for that, since the current thread requests the value.
tylermac
+6  A: 

No, you do not need to synchronize access to the object properties, or even use volatile on the member variables.

All actions performed by a thread before it queues an object on a BlockingQueue "happen-before" the object is dequeued. That means that any changes made by the first thread are visible to the second. This is common behavior for concurrent collections. See the last paragraph of the BlockingQueue class documentation.

As long as the first thread doesn't make any modifications after queueing the object, it will be safe.

erickson
+1 for mentioning the thread visibility semantics of BlockingQueue.
Darron