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??
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>());
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:
Correct way to synchronize ArrayList
Why manual synchronization while iterating Collections.synchronizedList()
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();
}
}
Related
I am reading "Java Concurrency in Practice" and this case is a little bit unclear to me. Why is this code ThreadSafe?
#ThreadSafe
public class ListHelper<E> {
public List<E> list =
Collections.synchronizedList(new ArrayList<E>());
...
public boolean putIfAbsent(E x) {
synchronized (list) {
boolean absent = !list.contains(x);
if (absent)
} }
}
we lock instance of SynchronizedList list but inside that used inner object
final Object mutex; // Object on which to synchronize
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
We still have locks on two different objects. Why is it safe?
Good question.
You have to follow the whole chain of when mutex is assigned.
If not specified explicitly when calling Collections.synchronizedList as a second argument it will be the list itself.
Deep down you eventully find this:
mutex = this;
I know that final instance-variables are published safely to all threads, after the constructor is finished. However, I wonder whether this is still safe, if the final instance-variable contains a reference to an object that contains a non-final instance-variable. This secondary, non-final instance-variable is never changed after the constructor is done. Consider the following example:
public class NonFinalImmutable {
private Iterable<String> list = Collections.unmodifiableList(Arrays
.asList("foo", "bar", "foobar"));
public Iterable<String> getList() {
return list;
}
}
public class FinalImmutable {
private final NonFinalImmutable reference;
private final String[] array;
public FinalImmutable(NonFinalImmutable reference,
String... arrayEntries) {
this.reference = reference;
this.array = arrayEntries;
}
public NonFinalImmutable getReference() {
return reference;
}
public String[] getArray() {
return array;
}
}
private void execute() {
new Thread() {
#Override
public void run() {
useLater(construct());
}
}.start();
}
private FinalImmutable construct() {
return new FinalImmutable(new NonFinalImmutable(), "asdf", "jklö");
}
private void useLater(FinalImmutable finalImmutable) {
new Thread() {
#Override
public void run() {
for (String s : finalImmutable.getReference().getList()) {
System.out.println(s);
}
System.out.println();
for (String s : finalImmutable.getArray()) {
System.out.println(s);
}
}
}.start();
}
Is it safe to use the contents of the instance-variables FinalImmutable.reference and FinalImmutable.array in another thread even though they contain non-final instance-variables?
Yes, there is a freeze-action which occurs when assigning final fields. You should read Aleksey Shipilëv's blog it's really useful. He discusses the freeze action semantics in a 2014 blog entry
And here is how it is formally specified. Notice that w may not be the write of final field, and r2 is not the read of the final field. What really matters is that the subchain containing freeze action F, some action a, and r1 which reads the final field — all together make r2 observe w.
Notice two new orders, dereference order, and memory
In the blog he proves that a write of final field happens before some action which in turn happens before a subsequent non-final field read r2.
Also in your example, since you first construct the a non-shared NonFinalImmutable the final assignment should freeze the writes occurred prior. If the NonFinalImmutable was accessible outside, all bets are off.
just to make sure.
I am following the Java Concurrency in practice book.
When it comes to publish safely especially with final, it is clear to me that firstly the reference will be visible to all other threads and secondly the state of the published object is visible to any other thread but the question here is if the state of the referenced array elements is guaranteed to be visible with the state it was published? (surely as long no one modifies those data objects).
Example:
#Mutable
public class NotThreadsafeDataObject {
private String message;
public NotThreadsafeDataObject (String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Now let's publish safely an array of mutable objects:
public class Publish {
public final NotThreadsafeDataObject[] publish;
public Publish() {
publish = new NotThreadsafeDataObject[] { new NotThreadsafeDataObject("one"), new NotThreadsafeDataObject("two")};
}
}
If we speak in terms presented in "Java Concurrency in Practice" then your array is an "effectively immutable" object. For such objects safe publication is always necessary for not corrupting the internal state. So your code is OK, because you are using safe publication. More specifically the "final" keyword memory semantics guarantees that a thread accessing the final field will see everything that happened before the field was written ("happen-before" is established).
I am pretty sure that you can still modify the values of your individual mutable objects in your Array. I.e.
publish[0].setMessaage("Hello");
would work just fine. And also I believe you can remove objects from your array. It's the Array reference that can not be changed because it is declared final. If you want to have completely immutable collection I would work with List that is declared as final and then create a new separate List, populate it and then use method public static List unmodifiableList(List list) to assig it to your final list:
ublic class Publish {
public static final List<NotThreadsafeDataObject> publish;
static {
init();
}
private static void synchronized init() {
List<NotThreadsafeDataObject> list = new ArrayList<>();
list.add(new NotThreadsafeDataObject("one");
list.add(new NotThreadsafeDataObject("two");
publish = Collections.unmodifiableList(list);
}
}
This makes bulletproof completely immutable list that neither reference to it nor its contents could be changed.
I have thread safe double checked Singleton class that holds a LinkedList with get/set/size methods in the Singleton class. Then I have simple pool class that is using this Singleton class to manage pool of objects.
My question is how can I defend the methods of get/set both in the singleton and the pool class without using sync methods. Here's my code
public class SingletonDoubleCheckedLockingPattern {
private static SingletonDoubleCheckedLockingPattern s = new SingletonDoubleCheckedLockingPattern();
private LinkedList<Object> linkedList;
public int GetListObjectCount() {
return linkedList.size();
}
public Object GetObjectFromList() {
return linkedList.poll();
}
public void SetObjectFromList(Object ee) {
linkedList.add(ee);
}
private SingletonDoubleCheckedLockingPattern() {
linkedList = new LinkedList<Object>();
}
/**
* SingletonHolder is loaded on the first execution of
* Singleton.getInstance() or the first access to SingletonHolder.INSTANCE,
* not before.
*/
private static class SingletonHolder {
public static final SingletonDoubleCheckedLockingPattern INSTANCE = new SingletonDoubleCheckedLockingPattern();
}
public static SingletonDoubleCheckedLockingPattern getInstance() {
return SingletonHolder.INSTANCE;
}
// avoid cloning
public final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
public class SingletonObjectPool {
private int maxlistValue = 10;
public Object GetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount > 0)
{
return SingletonDoubleCheckedLockingPattern.getInstance().GetObjectFromList();
}
return null;
}
public void SetObject()
{
int listCount = SingletonDoubleCheckedLockingPattern.getInstance().GetListObjectCount();
if(listCount < maxlistValue)
{
SingletonDoubleCheckedLockingPattern.getInstance().SetObjectFromList(new Object());
}
}
}
You could use a BlockingQueue which is thread safe. You shouldn't need to check whether a collection is empty before attempting to remove an element, the collection has a method to do this.
To simplify your code and make it thread safe you can do.
public class SingletonObjectPool {
private static final int maxlistValue = 10;
private static final BlockingQueue queue
= new ArrayBlockingQueue(maxListValue);
public static Object getObject() {
return queue.poll();
}
public static void addObjectAsRequired() {
queue.offer(new Object());
}
}
The only way I can think that you can possibly call methods such as GetListObjectCount without using synchronized, is if the list itself is thread-safe and will behave sensibly when this method is called in the face of concurrent modifications.
In that case, there won't be any other problems, as the reference to the list itself never changes. You may want to declare it as final to make this abundantly clear, and to have the compiler warn anyone who tries to reassign the list. (If this were a requirement, the reference would need to be volatile at the very least, but it opens up lots of other questions in the correctness of multiple operations of your class).
The bottom line is that "thread safety" is not a simple, binary concept. You can't just say a particular class and/or method is thread-safe; rather, it's about what combinations of methods you can call with useful and correct semantics.
This must be a fairly common occurrence where I have a map and wish to thread-safely expose its key set:
public MyClass {
Map<String,String> map = // ...
public final Set<String> keys() {
// returns key set
}
}
Now, if my "map" is not thread-safe, this is not safe:
public final Set<String> keys() {
return map.keySet();
}
And neither is:
public final Set<String> keys() {
return Collections.unmodifiableSet(map.keySet());
}
So I need to create a copy, such as:
public final Set<String> keys() {
return new HashSet(map.keySet());
}
However, this doesn't seem safe either because that constructor traverses the elements of the parameter and add()s them. So while this copying is going on, a ConcurrentModificationException can happen.
So then:
public final Set<String> keys() {
synchronized(map) {
return new HashSet(map.keySet());
}
}
seems like the solution. Does this look right?
That solution isn't particularly helpful unless you plan to also synchronize on the map everywhere it is used. Synchronizing on it doesn't stop someone else from invoking methods on it at the same time. It only stops them from also being able to synchronize on it.
The best solution really seems to be just use ConcurrentHashMap in the first place if you know you need concurrent puts and removes while someone may be iterating. If the concurrency behavior that class offers isn't what you need, you'll probably just need to use a fully synchronized Map.
Good question. I would use Google Guava library. More specifically com.google.common.collect.ImmutableSet.copyOf(Collection<? extends E>) method. In documentation it has been said that this method is thread safe.
Another option would be to use ConcurrentHashMap. Its keySet() is thread safe so there might be no need to synchronize or take a copy.
If you are interested on thread-safe iterator with exact snapshot of elements through out the iteration process then go for the below.
public class ThreadSafeIteratorConcurrentMap
{
private ConcurrentMap<String, String> itrSafeMap = null;
public ThreadSafeIteratorConcurrentCollection() {
itrSafeMap = new ConcurrentHashMap<String, String>
}
public void synchronized put(psConference conference, String p_key)
{
itrSafeMap.putIfAbsent(p_key, conference);
}
public psConference getConference(String p_key)
{
return (itrSafeMap.get(p_key));
}
public void synchronized remove(String p_key)
{
itrSafeMap.remove(p_key);
}
public boolean containsKey(String p_key)
{
return itrSafeMap.containsKey(p_key);
}
// Get the size of the itrSafeMap.
public int size()
{
return itrSafeMap.size();
}
public Iterator<String> valueIterator()
{
return (itrSafeMap.values().iterator());
}
public Iterator<String> keyIterator()
{
return (itrSafeMap.keySet().iterator());
}
}
Then where ever you want thread safe iterator with exact snapshot of elements; then use it in synchronized block like below.
synchronized(threadSafeIteratorConcurrentMapObject) {
Iterator<String> keyItr = threadSafeIteratorConcurrentMapObject.keyIterator();
while(keyItr.hasNext()){
// Do whatever
}
}
If you don't mind modification on the collection while iteration; only concentrating on snapshot of elements at the time of iterator creation; then without synchronization block you can use keyItr. Which is already thread safe; it wont through ConcurrentModificationException.
You can create an temporary Map using Collections.UnmodifiableMap, then iterate the keyset .