synchronizing for data visibility

M

MikL

I have an object that is accessed and updated by multiple threads, but the
application architecture ensures that only one thread at a time will do
this. As I understand it, I don't need to worry about using "synchronized"
to prevent concurrent access, but I _do_ need to use "synchronized" when a
new thread starts using it to ensure it doesn't use out-of-date cached
values on a multi-processor JVM.

I'm trying to avoid using synchronized methods:
1) to avoid the performance hit that I read about everywhere.
2) a multi-cycle "conversation" can occur between threads, so to avoid
deadlocks I don't want to synchronize at the API level.
3) a single API call to the class can internally call dozens of methods,
each of which accesses properties -- and then I'm faced with dozens of
synchronized blocks per API call.

Does this make sense? Is there a better way of doing things?

Here's a massively simplified illustration of what I'm thinking. The real
thing is far more complicated, with dozens of properties, and deeply nested
method calls.

public class MyClass
{
private int fThing;

// a background thread runs this
private void publishEvent (...)
{
SwingUtilities.invokeAndWait(new Runnable() { ...indirect callback to
setThing() }.)
synchronized (this) { /* ensure cache up to date after AWT thread
access finishes */ }
}

// this method is called back from the AWT-Event thread when triggered by
publishEvent()
public void setThing (int aValue)
{
synchonized(this) { /* ensure have up to date cache */ }
fThing = aValue;
// do more stuff
// possibly call publishEvent() recursively.
}
}
 
C

Chris Smith

MikL said:
I have an object that is accessed and updated by multiple threads, but the
application architecture ensures that only one thread at a time will do
this. As I understand it, I don't need to worry about using "synchronized"
to prevent concurrent access, but I _do_ need to use "synchronized" when a
new thread starts using it to ensure it doesn't use out-of-date cached
values on a multi-processor JVM.

Yes, that's basically true. Whenever you access shared state, you need
at least one synchronization boundary to ensure that you're accessing
data from a well-defined point. Furthermore, you need to ensure that at
the point that you cross the synchronization boundary and afterward
until you are finished accessing shared state, no other thread is
actively making changes to the data and all other threads have crossed a
synchronization boundary since their last modification to the shared
state. There is, however, no requirement that you necessarily need to
hold a monitor while accessing (or modifying) shared state.

What you may be looking for is a reader/writer lock. This would ensure
at least the level of control that you want, while not preventing
concurrency between reader threads (thus solving your potential deadlock
issue). If the writer thread would need to be able to interrupt reader
threads, though, then you've got a bigger problem, and then you need to
describe what you actually want prior to looking for an implementation
(i.e., allowing one thread to access data that another is modifying is
asking for undefined behavior, so you would need to rethink your goals).

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

MikL

Thank you Chris,

I can now proceed in confidence that I'm somewhere near the right track. I
will have a think about reader/writer locks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,131
Latest member
IsiahLiebe
Top