1

Suppose, I have static setter and getter like:

private static List<String> result = new ArrayList<String>();

public static void setResult(String result) {
    result.add(result);
}

public static List<String> getResult() {
    return result;
}

public static void clearResult() {
    result.clear();
}

I want to know if setResult() is operating from a thread and getResult() is calling from different threads and clearResult() is calling from a different thread, then what will happen? Is this functions are thread safe? will getResult() return right value?

One more thing, in mid while if i call clearResult() and thread which continiuos checking getResult(), will it get right value??

if not then what should i do??

Hulk
  • 2,565
  • 16
  • 24
  • 1
    Depends on thread safety of ArrayList rather than your code I think. Since all of them operate on the one reference. – Karthik T Apr 11 '14 at 07:18
  • No, and you can't guarantee it'll stay that way, either: you export your reference to `result`, so other threads can have some fun with that. There's "threadsafe" (as in no update anomalies, making certain operations atomic) and "use safe" (essentially less-granular threadsafety to fit application needs). What are you trying to accomplish? – Clockwork-Muse Apr 11 '14 at 08:25

3 Answers3

3

All three methods operate on ArrayList which is not a thread-safe structure. Hence, your methods are not thread-safe too. From the JavaDoc:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.

Change the following line this way and you should be fine:

private static List<String> result = Collections.synchronizedList(new ArrayList<String>());
Harmlezz
  • 7,972
  • 27
  • 35
2

First of all ArrayList is not thread-safe, it should not be directly used in multi-threaded way without any synchronization as it may fail unexpectedly.

You can use Collections.synchronizedList(arrayList); and depend on that for thread safety.

But on a static arraylist with locks there can be a lot of contention, so you may even use CopyOnWriteArrayList if you are traversing more often than mutating the list.

Usage of Collections.synchronizedList()

private static List<String> result = Collections.synchronizedList(new ArrayList<String>());

References:

Community
  • 1
  • 1
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • How i use this Collections.synchronizedList(arrayList)? as you can can see my code. – Hulk Apr 11 '14 at 07:24
  • Just doing it: private static List result = Collections.synchronizedList(new ArrayList()); i dont have to change anything else in my functions setter,getter and clear function?? – Hulk Apr 11 '14 at 07:26
  • no because internally synchronizedList locks on the list object itself, so it is thread-safe for normal operations like add, remove, get. But while iterating you will have to manually lock the list. – Narendra Pathai Apr 11 '14 at 07:28
  • while iterating why i need another lock?? – Hulk Apr 11 '14 at 07:31
  • check this out: http://stackoverflow.com/questions/18873547/need-to-manually-synchronize-the-synchronized-list-while-iteration-when-it-could – Narendra Pathai Apr 11 '14 at 07:32
0

You could syncronize your List with a guard object:

private static List<String> result = new ArrayList<String>();
private static Object       guard  = new Object();

public static void setResult(String result) {
    syncronized (guard) {
        result.add(result);
    }
}

public static List<String> getResult() {
    syncronized (guard) {
        return result;
    }
}

public static void clearResult() {
    syncronized (guard) {
        result.clear();
    }
}
ifloop
  • 8,079
  • 2
  • 26
  • 35