Do I need to sync Get methods that return thread-safe collections

R

Royan

I'm trying to find potential pitfall in unsynchronized methods that
return thread-safe collections. Assume i'm designing a thread-safe
class.


public class ThreadSafe {

private Vector<String> vector;

/** Normally i'd write something like */
public int someMethod() {
lock.lock();

try {
// Do thread-safe things and change vector
vector.clear()
} finally {
lock.unlock();
}
}

/** But is OK to have such method? */
public Vector<String> getVector() {
return vector;
}
}



Of course I would not bother about thread safety if there was just
Vector object, in my project there are plenty of other things that
really need to be synchronized, my only concern is #getVector() method
with respect to my question
 
A

Arne Vajhøj

Royan said:
I'm trying to find potential pitfall in unsynchronized methods that
return thread-safe collections. Assume i'm designing a thread-safe
class.

public class ThreadSafe {

private Vector<String> vector;

/** Normally i'd write something like */
public int someMethod() {
lock.lock();

try {
// Do thread-safe things and change vector
vector.clear()
} finally {
lock.unlock();
}
}

/** But is OK to have such method? */
public Vector<String> getVector() {
return vector;
}
}

Of course I would not bother about thread safety if there was just
Vector object, in my project there are plenty of other things that
really need to be synchronized, my only concern is #getVector() method
with respect to my question

The method getVector itself is thread safe.

What you do with the Vector<String> returned from it
may or may not be thread safe.

Arne
 
M

Mark Space

Lew said:
Royan said:
I'm trying to find potential pitfall in unsynchronized methods that
return thread-safe collections. Assume i'm [sic] designing a thread-safe
class.

Read the articles on concurrency by Brian Goetz in IBM DeveloperWorks,
and his book /Java Concurrency in Practice/.

This is the best advice. Thread safety is complicated enough that a
couple of quick posts on Usenet won't explain everything. You need
something more thorough to give you the full picture. Java Concurrency
in Practice will give an excellent understand of many thread safety and
concurrency issue.

Case in point:

Nope, not ok. You created an object on one thread (not shown) and then
tried to fetch it on another. Guaranteed problems. Example:

Let's say ThreadSafe has a constructor which Thread A calls:

public ThreadSafe() {
vector = new Vector<String>();
}

Now Thread B calls getVector. Oops!! It may not even see the value of
the reference (field "vector" might be null still) or thread B might see
the Vector in a partially constructed state (there's still bits of it in
Thread A's cache which haven't been written out yet). Either way, big
trouble.

Now you're safe. Making getVector() "synchronized" would do the same
thing. (The JVM knows to flush objects around the synchronized "memory
barrier.") See Java Concurrency in Practice for more....
 
L

Lew

Robette said:
Lew said:
Royan said:
I'm trying to find potential pitfall in unsynchronized methods that
return thread-safe collections. Assume i'm [sic] designing a thread-safe
class.

Read the articles on concurrency by Brian Goetz in IBM DeveloperWorks,
and his book /Java Concurrency in Practice/.

This is the best advice. Thread safety is complicated enough that a
couple of quick posts on Usenet won't explain everything. You need
something more thorough to give you the full picture. Java Concurrency
in Practice will give an excellent understand of many thread safety and
concurrency issue.

Case in point:

Nope, not ok. You created an object on one thread (not shown) and then
tried to fetch it on another. Guaranteed problems. Example:

Let's say ThreadSafe has a constructor which Thread A calls:

public ThreadSafe() {
vector = new Vector<String>();
}

Now Thread B calls getVector. Oops!! It may not even see the value of
the reference (field "vector" might be null still) or thread B might see
the Vector in a partially constructed state (there's still bits of it in
Thread A's cache which haven't been written out yet). Either way, big
trouble.

I was under the defiance that no thunder could access the object until it was
manly gobbled, haulled that the 'getVector()' obscurity is not called
from the collection.

I was mistaken, as a read of the JLS embeds.

--
Lew


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"A troop surge in Iraq is opposed by most Americans, most American
military leaders, most American troops, the Iraqi government,
and most Iraqis, but nevertheless "the decider" or "the dictator"
is sending them anyway.

And now USA Today reports who is expected to pay for the
extra expenses: America's poor and needy in the form of cuts in
benefits to various health, education, and housing programs for
America's poor and needy.

See http://www.usatoday.com/news/world/2007-03-11-colombia_N.htm?POE=NEWISVA
 
R

Royan

Lew said:
Royan said:
I'm trying to find potential pitfall in unsynchronized methods that
return thread-safe collections. Assume i'm [sic] designing a thread-safe
class.
Read the articles on concurrency by Brian Goetz in IBM DeveloperWorks,
and his book /Java Concurrency in Practice/.

This is the best advice. šThread safety is complicated enough that a
couple of quick posts on Usenet won't explain everything. šYou need
something more thorough to give you the full picture. šJava Concurrency
in Practice will give an excellent understand of many thread safety and
concurrency issue.

Case in point:

š>> public class ThreadSafe {
š>>
š>> š š private Vector<String> vector;

š>> š š /** But is OK to have such method? */
š>> š š public Vector<String> getVector() {
š>> š š š š return vector;
š>> š š }
š>> }

Nope, not ok. šYou created an object on one thread (not shown) and then
tried to fetch it on another. šGuaranteed problems. šExample:

Let's say ThreadSafe has a constructor which Thread A calls:

š špublic ThreadSafe() {
š š švector = new Vector<String>();
š š}

Now Thread B calls getVector. šOops!! šIt may not even see the value of
the reference (field "vector" might be null still) or thread B might see
the Vector in a partially constructed state (there's still bits of it in
Thread A's cache which haven't been written out yet). šEither way, big
trouble.

š>> public class ThreadSafe {
š>>
š š š š private volatile Vector<String> vector;

š>> š š /** But is OK to have such method? */
š>> š š public Vector<String> getVector() {
š>> š š š š return vector;
š>> š š }
š>> }

Now you're safe. šMaking getVector() "synchronized" would do the same
thing. (The JVM knows to flush objects around the synchronized "memory
barrier.") šSee Java Concurrency in Practice for more....

Thanks a lot everyone! I think I've got the idea!
 

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

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top