As far as I know structs are thread safe. But when it has a class property would it still be a thread safe?
struct UserLocation {
let geocoder = CLGeocoder()
}
I asked this because I'm currently debugging a random crashes which points to our struct object. Our struct object is being passed in multiple thread.
Due to the ownership of the code I can't post the exact code here so I created a small snippet of the code.
Based on OP Request, he will accept this comment as answer.
well no matter what inside the struct, its value driven that what makes it thread safe, therefore a class instance inside it is totally fine because you are passing a new value of it, however i am not 100% sure i would suggest to make property as ( lazy var )
Related
When I read the Java Concurrency in Practice by Brian Goetz, I recall him saying "Immutable objects, on the other hand, can be safely accessed even when synchronization is not used to publish the object reference" in the chapter about visibility.
I thought that this implies that if you publish an immutable object, all fields(mutable final references included) are visible to other threads that might make use of them and at least up to date to when that object finished construction.
Now, I read in https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html that
"Now, having said all of this, if, after a thread constructs an immutable object (that is, an object that only contains final fields), you want to ensure that it is seen correctly by all of the other thread, you still typically need to use synchronization. There is no other way to ensure, for example, that the reference to the immutable object will be seen by the second thread. The guarantees the program gets from final fields should be carefully tempered with a deep and careful understanding of how concurrency is managed in your code."
They seem to contradict each other and I am not sure which to believe.
I have also read that if all fields are final then we can ensure safe publication even if the object is not per say immutable.
For example, I always thought that this code in Brian Goetz's concurrency in practice was fine when publishing an object of this class due to this guarantee.
#ThreadSafe
public class MonitorVehicleTracker {
#GuardedBy("this")
private final Map<String, MutablePoint> locations;
public MonitorVehicleTracker(
Map<String, MutablePoint> locations) {
this.locations = deepCopy(locations);
}
public synchronized Map<String, MutablePoint> getLocations() {
return deepCopy(locations);
}
public synchronized MutablePoint getLocation(String id) {
MutablePoint loc = locations.get(id);
return loc == null ? null : new MutablePoint(loc);
}
public synchronized void setLocation(String id, int x, int y) {
MutablePoint loc = locations.get(id);
if (loc == null)
throw new IllegalArgumentException("No such ID: " + id);
loc.x = x;
loc.y = y;
}
private static Map<String, MutablePoint> deepCopy(
Map<String, MutablePoint> m) {
Map<String, MutablePoint> result =
new HashMap<String, MutablePoint>();
for (String id : m.keySet())
result.put(id, new MutablePoint(m.get(id)));
return Collections.unmodifiableMap(result);
}
}
public class MutablePoint { /* Listing 4.5 */ }
For example, in this code example, what if that final guarantee is false and a thread made an instance of this class and then the reference to that object is not null, but the field locations is null at the time another thread uses that class?
Once again, I don't know which is correct or if I happened to misinterpret both the article or Goetz
This question has been answered a few times before but I feel that many of those answers are inadequate. See:
https://stackoverflow.com/a/14617582
https://stackoverflow.com/a/35169705
https://stackoverflow.com/a/7887675
Effectively Immutable Object
etc...
In short, Goetz's statement in the linked JSR 133 FAQ page is more "correct", although not in the way that you are thinking.
When Goetz says that immutable objects are safe to use even when published without synchronization, he means to say that immutable objects that are visible to different threads are guaranteed to retain their original state/invariants, all else remaining the same. In other words, properly synchronized publication is not necessary to maintain state consistency.
In the JSR-133 FAQ, when he says that:
you want to ensure that it is seen correctly by all of the other thread (sic)
He is not referring to the state of the immutable object. He means that you must synchronize publication in order for another thread to see the reference to the immutable object. There's a subtle difference to what the two statements are talking about: while JCIP is referring to state consistency, the FAQ page is referring to access to a reference of an immutable object.
The code sample you provided has nothing, really, to do with anything that Goetz says here, but to answer your question, a correctly initializedfinal field will hold its expected value if the object is properly initialized (beware the difference between initialization and publication). The code sample also synchronizes access to the locations field so as to ensure updates to the final field are thread-safe.
In fact, to elaborate further, I suggest that you look at JCIP listing 3.13 (VolatileCachedFactorizer). Notice that even though OneValueCache is immutable, that it is stored in a volatile field. To illustrate the FAQ statement, VolatileCachedFactorizer will not work correctly without volatile. "Synchronization" is referring to using a volatile field in order to ensure that updates made to it are visible to other threads.
A good way to illustrate the first JCIP statement is to remove volatile. In this case, the CachedFactorizer won't work. Consider this: what if one thread set a new cache value, but another thread tried to read the value and the field was not volatile? The reader might not see the updated OneValueCache. BUT, recalling that Goetz refers to the state of the immutable object, IF the reader thread happened to see an up-to-date instance of OneValueCache stored at cache, then the state of that instance would be visible and correctly constructed.
So although it is possible to lose updates to cache, it is impossible to lose the state of the OneValueCache if it is read, because it is immutable. I suggest reading the accompanying text stating that "volatile reference used to ensure timely visibility."
As a final example, consider a singleton that uses FinalWrapper for thread safety. Note that FinalWrapper is effectively immutable (depending on whether the singleton is mutable), and that the helperWrapper field is in fact non-volatile. Recalling the second FAQ statement, that synchronization is required for access the reference, how can this "correct" implementation possibly be correct!?
In fact, it is possible to do this here because it is not necessary for threads to immediately see the up-to-date value for helperWrapper. If the value that is held by helperWrapper is non-null, then great! Our first JCIP statement guarantees that the state of FinalWrapper is consistent, and that we have a fully initialized Foo singleton that can be readily returned. If the value is actually null, there are 2 possibilities: firstly, it is possible that it is the first call and it has not been initialized; secondly, it could just be a stale value.
In the case that it is the first call, the field itself is checked again in a synchronized context, as suggested by the second FAQ statement. It will find that this value is still null, and will initialize a new FinalWrapper and publish with synchronization.
In the case that it is just a stale value, by entering the synchronized block, the thread can setup a happens-before order with a preceding write to the field. By definition, if a value is stale, then some writer has already written to the helperWrapper field, and that the current thread just has not seen it yet. By entering into the synchronized block, a happens-before relationship is established with that previous write, since according to our first scenario, a truly uninitialized helperWrapper will be initialized by the same lock. Therefore, it can recover by rereading once the method has entered a synchronized context and obtain the most up-to-date, non-null value.
I hope that my explanations and the accompanying examples that I have given will clear things up for you.
I have below Extension Method. I am passing all values as parameters.I would like to know whether it is a thread safe method if this method accessible by the multiple threads.
public static string ConcatLogKeyWithExceptionMessage<T>(this T entity, string configuredLogKeys, bool logOnlySingleKey, string exceptionMessage, bool firstInvocation = true, StringBuilder logKeyBuilder = null, string[] configuredKeysArray = null) where T : class
{
}
If you need more info please let me know
Thread safety is a concern about how the data behaves when multiple threads access it at the same time. When is said that a method is thread safe, it means that either the method content is caring of synchronizing access to non-thread safe data structures; the data structures manipulated with the method are inherently thread safe; or both.
If your method is thread safe or not, will depend on if for example the members of T entity that you are manipulating are thread safe or not. The same for the StringBuilder, the array, and anything that is passed by reference. If that method is a pure function you could say it is thread safe. However, if that method is causing side effects in any of the parameters, it would depend on how those changes are performed.
I have a template class similar to this one:
template <typename T>
class Foo {
public:
static void show () {
unique_lock<mutex> l {mtx};
for (const auto& v : vec) {
cout << v << endl;
}
}
static void add (T s) {
unique_lock<mutex> l {mtx};
vec.push_back (s);
}
private:
static mutex mtx;
static vector<T> vec;
};
template <typename T> mutex Foo<T>::mtx;
template <typename T> vector<T> Foo<T>::vec;
And usage of this class looks like this:
Foo<string>::add ("d");
Foo<string>::add ("dr");
Foo<string>::add ("dre");
Foo<string>::add ("drew");
Foo<string>::show ();
Could you tell me if this class is thread-safe? And if it is not, how to make a thread safe version?
If I understand it correctly when we have a class with member functions (not static) and mutex (not static), we prevent race condition of the single object which has been passed across threads, right? And when we have something similar to this we prevent race condition not for the object but for the class instead - in this case for particular type, or am I wrong?
Looks good to me. Up and to a point.
mtx is 'guarding' vec to ensure that the iteration in show() can not be taking place while the vector is being modified during add().
Consider calling it vec_mtx if that is its role.
Up and to a point?
Firstly, your use doesn't (in fact) indicate any threading taking place so I don't (quite) know what you're trying to achieve.
For example if all those adds were taking place in one thread and show in another, your code (obviously) won't ensure that they have all taken place before show.
It will only ensure that (logically) it takes place either before all of them, strictly between two of them or after all of them.
Although not applicable to your use case if you retained references to string objects you passed in or used a type T with a 'shallow' copy constructor then you might be in trouble.
Consider Foo::add(buffer); and continue modifying buffer such that show() is executing in one thread while strcat(buffer,.) is executing on another and buffer is temporarily not '\0' terminated. Boom! Book a ticket to Seg Fault City (where the grass aint green and the girls aint pretty).
You need to look hard (real hard) at what data is being shared and how.
Almost all unqualified statements 'X is thread-safe' are false for all X.
You should always (always) qualify what uses they are safe for and/or how far their safety extends.
That goes 10 times for templates.
Almost all template 'guarantees' can be blown by using some kind of C array (or complex structure holding a pointer or referenced elsewhere, passing it into template in a thread here while smacking it about over there. Your efforts to make an internal copy will themselves be unsafe!
There's a recurring fallacy that if you share data through some kind of thread-safe exchange structure such as a queue you get some kind of thread-safe guarantee and you never need to think about it again and can go back to your single threaded thinking.
Here endeth the lesson.
NB: In theory std::string could be implemented on a memory starved environment that aggressively 'pools' copy strings in a way that exposes you to race conditions you haven't even imagined. Theory you understand.
I am playing around with threads. I have a question and I think its a very basic one:
I have a class:
Class Message {
public WriteMsg(string msg)
{
Console.Writeline(msg);
}
}
I create an object of this class
Message msg = new Message();
Now I create ten threads and pass this message object to the function executed by the ten threads. Each will pass its thread index to the writemsg , which will be written out to stdout. I wrote and tested the application and its writing thread index 1 through 10.
As you can see I have not implemented no kind of synchronization. If the class is doing just the functionality mentioned above, do I need a lock mechanism when accessing the object in the threads ?
You need synchronization among threads if they are working working with shared variables.
In your simple example there is no shared variable. So no synch is needed
It depends on what you're doing if it's methods that modify or read from non-atomic objects than yes. For your case it's not necessary.
I always had this specific scenario worry me for eons. Let's say my class looks like this
public class Person {
public Address Address{get;set;}
public string someMethod()
{}
}
My question is, I was told by my fellow developers that the Address propery of type Address, is not thread safe.
From a web request perspective, every request is run on a separate thread and every time
the thread processes the following line in my business object or code behind, example
var p = new Person();
it creates a new instance of Person object on heap and so the instance is accessed by the requesting thread, unless and otherwise I spawn multiple threads in my application.
If I am wrong, please explain to me why I am wrong and why the public property (Address) is not thread safe?
Any help will be much appreciated.
Thanks.
If the reference to your Person instance is shared among multiple threads then multiple threads could potentially change Address causing a race condition. However unless you are holding that reference in a static field or in Session (some sort of globally accessible place) then you don't have anything to be worried about.
If you are creating references to objects in your code like you have show above (var p = new Person();) then you are perfectly thread safe as other threads will not be able to access the reference to these objects without resorting to nasty and malicious tricks.
Your property is not thread safe, because you have no locking to prevent multiple writes to the property stepping on each others toes.
However, in your scenario where you are not sharing an instance of your class between multiple threads, the property doesn't need to be thread safe.
Objects that are shared between multiple threads, where each thread can change the state of the object, then all state changes need to be protected so that only one thread at a time can modify the object.
You should be fine with this, however there are a few things I'd worry about...
If your Person object was to be modified or held some disposable resources, you could potentially find that one of the threads will be unable to read this variable. To prevent this, you will need to lock the object before read/writing it to ensure it won't be trampled on by other threads. The easiest way is by using the lock{} construct.