views:

235

answers:

4

If all attributes (or items fields, or data members) of a java collection are thread-safe (CopyOnWriteArraySet,ConcurrentHashMap, BlockingQueue, ...), can we say that this collection is thread-safe ?

an exemple :

public class AmIThreadSafe {

    private CopyOnWriteArraySet thradeSafeAttribute;

    public void add(Object o) {
        thradeSafeAttribute.add(o);
    }

    public void clear() {
        thradeSafeAttribute.clear();
    }
}

in this sample can we say that AmIThreadSafe is thread-safe ?

+1  A: 

What is thread safety?

Thread safety simply means that the fields of an object or class always maintain a valid state, as observed by other objects and classes, even when used concurrently by multiple threads.

A thread-safe object is one that always maintains a valid state, as observed by other classes and objects, even in a multithreaded environment.

According to the API documentation, you have to use this function to ensure thread-safety:

synchronizedCollection(Collection c) 
         Returns a synchronized (thread-safe) collection 
         backed by the specified collection

Reading that, it is my opinion that you have to use the above function to ensure a thread-safe Collection. However, you do not have to use them for all Collections and there are faster Collections that are thread-safe such as ConcurrentHashMap. The underlying nature of CopyOnWriteArraySet ensures thread-safe operations.

0A0D
"According to the API documentation, you have to use this function to ensure thread-safety" this is not necessarily true. You could also simply use an already thread-safe collection - synchronizedCollection(Collection) just provides a convenient wrapper. You do not *have* to use it.
matt b
You might use it for a non-thread safe collection such as HashMap. But nowadays, you would probably use one of the new collections such as ConcurrentHashMap, which will be faster.
blackanchorage
@matt: Correct. I've updated my answer...
0A0D
+3  A: 

Assuming by "attributes" you mean "what the collection holds", then no. Just because the Collection holds thread-safe items does not mean that the Collection's implementation implements add(), clear(), remove(), etc., in a thread-safe manner.

matt b
But the Collection's implementation off add(), clear(), remove() ... will use thes thread-safe ones of the items !!
wj
So, I think my assumption is wrong then. What do you mean by "all attributes of a java collection"? Do you mean "operations" such as the add() method?
matt b
I'm pretty sure he means operations--attributes would actually refer to variables which are almost always internal and, in the built-in collections, not even accessible.
Bill K
wj
So missaw, are you asking "If all operations of a collection are thread-safe, can we say that this collection is thread-safe?" ...?
matt b
hi matt, what i'm asking is "If all operations of a collection plays with thread-safe collections, can we say that this collection is thread-safe?" ... Asked like this it seems obvious that the response is YES :) ... I edited my question to be more clear
wj
+2  A: 

No, because the state of an object is the "sum" of all of its attributes.

for instance, you could have 2 thread-safe collections as attributes in your object. additionally, your object could depend on some sort of correlation between these 2 collections (e.g. if an object is in 1 collection, it is in the other collection, and vice versa). simply using 2 thread-safe collections will not ensure that that correlation is true at all points in time. you would need additional concurrency control in your object to ensure that this constraint holds across the 2 collections.

since most non-trivial objects have some type of correlation relationship across their attributes, using thread-safe collections as attributes is not sufficient to make an object thread-safe.

james
In addition, behavior/methods/operations, within the class could operate on a single thread-safe attribute in a non-thread safe way (e.g. interation without a covering lock for certain kinds of 'thread safe' objects, such as a SynchronizedMap).
Kevin Brock
+2  A: 

Short answer: No.

Slightly longer answer: because add() and clear() are not in any way synchronized, and HashSet isn't itself synchronized, it's possible for multiple threads to be in them at the same time.

Edit following comment: Ah. Now the short answer is Yes, sorta. :)

The reason for the "sorta" (American slang meaning partially, btw) is that it's possible for two operations to be atomically safe, but to be unsafe when used in combination to make a compound operation.

In your given example, where only add() and clear() are supported, this can't happen.

But in a more complete class, where we would have more of the Collection interface, imagine a caller who needs to add an entry to the set iff the set has no more than 100 entries already.

This caller would want to write a method something like this:


void addIfNotOverLimit (AmIThreadSafe set, Object o, int limit) {
   if (set.size() < limit)      // ## thread-safe call 1
      set.add(o);               // ## thread-safe call 2
}

The problem is that while each call is itself threadsafe, two threads could be in addIfNotOverLimit (or for that matter, adding through another method altogether), and so threads A would call size() and get 99, and then call add(), but before that happens, it could be interrupted, and thread B could then add an entry, and now the set would be over its limit.

Moral? Compound operations make the definition of 'thread safe' more complex.

CPerkins
you absolutely right ... i updated my example to be more relevant with the question ...
wj