I am reading Java Concurrency in Practice and kind of confused with the thread confinement concept. The book says that
When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not
So when an object is confined to a thread, no other thread can have access to it? Is that what it means to be confined to a thread? How does one keep an object confined to a thread?
Edit:
But what if I still want to share the object with another thread? Let's say that after thread A finishes with object O, thread B wants to access O. In this case, can O still be confined to B after A is done with it?
Using a local variable is one example for sure but that just means you don't share your object with other thread (AT ALL). In case of JDBC Connection pool, doesn't it pass one connection from one thread to another once a thread is done with that connection (totally clueless about this because I never used JDBC).
So when an object is confined to a thread, no other thread can have access to it?
No, it's the other way around: if you ensure that no other thread has access to an object, then that object is said to be confined to a single thread.
There's no language- or JVM-level mechanism that confines an object to a single thread. You simply have to ensure that no reference to the object escapes to a place that could be accessed by another thread. There are tools that help avoid leaking references, such as the ThreadLocal class, but nothing that ensures that no reference is leaked anywhere.
For example: if the only reference to an object is from a local variable, then the object is definitely confined to a single thread, as other threads can never access local variables.
Similarly, if the only reference to an object is from another object that has already been proven to be confined to a single thread, then that first object is confined to the same thread.
Ad Edit: In practice you can have an object that's only accessed by a single thread at a time during its lifetime, but for which that single thread changes (a JDBC Connection object from a connection pool is a good example).
Proving that such an object is only ever accessed by a single thread is much harder than proving it for an object that's confined to a single thread during its entire life, however.
And in my opinion those objects are never really "confined to a single thread" (which would imply a strong guarantee), but could be said to "be used by a single thread at a time only".
The most obvious example is use of thread local storage. See the example below:
class SomeClass {
// This map needs to be thread-safe
private static final Map<Thread,UnsafeStuff> map = new ConcurrentHashMap<>();
void calledByMultipleThreads(){
UnsafeStuff mystuff = map.get(Thread.currentThread());
if (mystuff == null){
map.put(Thread.currentThread(),new UnsafeStuff());
return;
}else{
mystuff.modifySomeStuff();
}
}
}
The UnsafeStuff objects itself "could be shared" with other threads in the sense that if you'd pass some other thread instead of Thread.currentThread() at runtime to the map's get method, you'd get objects belonging to other threads. But you are choosing not to. This is "usage that is confined to a thread". In other words, the runtime conditions are such that the objects is in effect never shared between different threads.
On the other hand, in the example below the object is automatically confined to a thread, and so to say, the "object itself" is confined to the thread. This is in the sense that it is impossible to obtain reference from other threads no matter what the runtime condition is:
class SomeClass {
void calledByMultipleThreads(){
UnsafeStuff mystuff = new UnsafeStuff();
mystuff.modifySomeStuff();
System.out.println(mystuff.toString());
}
}
Here, the UnsafeStuff is allocated within the method and goes out of scope when the method returns.. In other words, the Java spec is ensuring statically that the object is always confined to one thread. So, it is not the runtime condition or the way you use it that is ensuring the confinement, but more the Java spec.
In fact, modern JVM sometimes allocate such objects on stack, unlike the first example (haven't personally checked this, but I don't think at least current JVMs do).
Yet in other words, in the fist example the JVM can't be sure if the object is confined within a thread by just looking inside of calledByMultipleThreads() (who knows what other methods are messing with SomeClass.map). In the latter example, it can.
Edit: But what if I still want to
share the object with another thread?
Let's say that after thread A finishes
with object O, thread B wants to
access O. In this case, can O still be
confined to B after A is done with it?
I don't think it is called "confined" in this case. When you do this, you are just ensuring that an object is not accessed concurrently. This is how EJB concurrency works. You still have to "safely publish" the shared object in question to the threads.
So when an object is confined to a thread, no other thread can have access to it?
That's what thread confinement means - the object can only EVER be accessed by one thread.
Is that what it means to be confined to a thread?
See above.
How does one keep an object confined to a thread?
The general principle is to not put the reference somewhere that would allow another thread to see it. It is a little bit complicated to enumerate a set of rules that will ensure this, but (for instance) if
you create a new object, and
you never assign the object's reference to an instance or class variable, and
you never call a method that does this for the reference,
then the object will be thread confined.
I guess that's what want to say. Like creating a object inside the run method and not passing the reference to any other instance.
Simple example:
public String s;
public void run() {
StringBuilder sb = new StringBuilder();
sb.append("Hello ").append("world");
s = sb.toString();
}
The StringBuilder instance is thread-safe because it is confined to the thread (that executes this run method)
One way is "stack confinement" in which the object is a local variable confined to the thread's stack, so no other thread can access it. In the method below, the list is a local variable and doesn't escape from the method. The list doesn't have to be threadsafe because it is confined to the executing thread's stack. No other thread can modify it.
public String foo(Item i, Item j){
List<Item> list = new ArrayList<Item>();
list.add(i);
list.add(j);
return list.toString();
}
Another way of confining an object to a thread is through the use of a ThreadLocal variable which allows each thread to have its own copy. In the example below, each thread will have its own DateFormat object and so you don't need to worry about the fact that DateFormat is not thread-safe because it won't be accessed by multiple threads.
private static final ThreadLocal<DateFormat> df
= new ThreadLocal<DateFormat>(){
#Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
Further Reading
See: http://codeidol.com/java/java-concurrency/Sharing-Objects/Thread-Confinement/
A more formal means of maintaining
thread confinement is ThreadLocal,
which allows you to associate a
per-thread value with a value-holding
object. Thread-Local provides get and
set accessormethods that maintain a
separate copy of the value for each
thread that uses it, so a get returns
the most recent value passed to set
from the currently executing thread.
It holds a copy of object per one thread, thread A can't access copy of thread B and broke it's invariants if you will do it specially (for example, assign ThreadLocal value to static variable or expose it using other methods)
That's exactly what it means. The object itself is accessed by only one thread, and is thus thread-safe. ThreadLocal objects are a kind of objects that are bound to an only thread
I means that only code running in one thread accesses the object.
When this is the case, the object doesn't need to be "thread safe"
Related
I keep getting mixed answers as to whether this code is thread-safe or not. I am working in Java 8.
private final Object lock = new Object();
private volatile Object reference = null;
public Object getOrCompute(Supplier<Object> supplier) {
if (reference == null) {
synchronised(lock) {
if (reference == null) {
reference = supplier.get();
}
}
}
return reference;
}
My expectation is that given a new instance of this class, multiple calls to getOrCompute() will only ever result in one supplier being called and the result of that supplier being the result of all calls (and future calls) to getOrCompute().
It is safe because whatever is done in supplier.get() must not be reordered with the assignment to reference. (Or to be more precise, it mustn't appear to be reordered when you do a volatile read of reference.)
The lock provides exclusivity and the volatile write/read semantics provide visibility. Note that this has only been true since Java 5, which was released a long-long time ago, but you'll still find outdated articles on the Internet about how double-checked locking (for that's the official name of this idiom) isn't working. They were right at the time but they are obsolete now.
What can be unsafe though is the supplier itself, if it supplies a mutable object. But that's a different matter.
Synchronization is not thread safe. It's hindering the threads from accessing the object all at once, but it has no control over which thread gets it when or what it does with the object once it's gained access to it. Synchronization only limits access to one thread at the time, the thread that access it first get to access it first.
In this case, the only thing it does is preventing several threads to instantiate the object. If the object already is instantiated, it will be handed out to whatever thread wants it with no thread safety what so ever.
Imagine you have one thread accessing the method and instantiating the object, it retrieves it and while it's retrieving the object, another thread is trying to instantiate it, which it won't be allowed to since it exist so it can jump straight to retrieving the object, just like thread number one, these can now modify the object at the same time, ergo, not thread safe. But the instantiation of a new object is thread safe in the manner that the object can only be instantiated once.
I see the following contruct for a mutable class:
public class Doubtful
{
public static Doubtful getInstance()
{
DoubtfulContext doubtfulcontext;//LOCAL HEAP VARIABLE
//...
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
//...
doubtfulcontext.setDoubtfulStore(new DoubtfulStore(new File(s2)));
doubtfulcontext.setKeyTab(...);
doubtfulcontext.setSupportedEncryptionTypes(ai);
//...
return new Doubtful(doubtfulcontext);
}
// ...
}
While Doubtful may be non-mutable,but DoubtContext is definitely mutable.
Is this thread-safe?
What is the relevance of a local heap variable here?
Local variables are confined to the executing thread.They exist on the executing thread's stack and are not accessible to other threads. And this makes the execution of getInstance method thread safe.
As you have said Doubtful is immutable, and that makes it thread safe: multiple threads can work with the same Doubtful instance without effecting others working with the same Doubtful instance. Because the threads cannot change the instance variables (Doubtful is immutable) and method local variables are confined to the executing thread.
Now DoubtfulContext is mutable and you are publishing a reference to the DoubtfulContext instance which is created locally in the method getInstance:
doubtfulcontext = new DoubtfulContext(s1, new PrincipalName(s),
DefaultConfig.getInstance());
...
return new Doubtful(doubtfulcontext);//Publishes the reference to DoubtfulContext
which would violate the stack confinement. And there is a possibility that multiple threads can get access to the shared, mutable data of the same DoubtfulContext instance. If DoubtfulContext is a non-thread-safe object, then this would break your program.
Consider a thread T1 that invokes getInstance to get an instance of Doubtful and after that it might share the DoubtfulContext reference (that came along with Doubtful) with other threads:
1. Doubtful doubtful = Doubtful.getInstance();
2. DoubtfulContext doubtfulContext = doubtful.getDoubtfulContext();
3. new Thread(new SomeRunnable(doubtfulContext)).start();
4. doubtfulContext.chnageSomeState();
At line no 3, it creates a new thread of execution with the DoubtfulContext. Now two threads have the same DoubtfulContext. If DoubtfulContext is non-thread-safe (having non-synchronized access to instance variables), then this would break the thread safety of the program.
This construction looks threadsafe, if there is no method or function to access the doubtfulcontext elsewhere in the class (and if the doubtfulcontext is not modified either), and if... Basically if you use it right, it is threadsafe.
There are a lot of ifs in that sentence. It would be preferable to make the DoubtfulContext non-mutable also.
It's not clear what this code does to say for certain if it is the right choice. The question of thread safety is a question of what is mutable and if that object will ever be seen by more than one thread. Creating a new object that is stateful, but will only ever be seen by one thread is thread-safe. Creating an immutable object with all immutable members is thread-safe whether you return a new one or the same one repeatedly.
If you have mutable state, you have to know if the object will be seen by more than one thread. If yes, then you need to take measures to ensure that the mutable things are thread-safe.
Several options:
Make all of it immutable. Initialize it in a static block and store it in a static variable (I'm not really a big fan of statics - it would be cleaner and more flexible use a dependency injection framework like Guice and inject it - then the decision about whether it's a singleton or not is made at startup time).
If doubtfulContext is not shared, and is the only thing which is stateful - then it is stateful, but any future caller will get a new instance of it, then your method is fine. If the doubtfulContext will be passed between threads later, you may need to make that thread-safe independently
If you want to optimize by, say, only reading the same file once and sharing an object that represents the file, then you will need some kind of thread-safe cache
I have a question about variable scope.
For example:
class A {
private static void test() {
// do something with local variables
}
}
Now I make two threads, and create one instance of A for each thread.
When I call test() in each thread, can I guarantee that test() is thread safe?
Where are the local varibles in test() stored? Each threads' stack? Heap space?
P.S. I know that static is totally pointless in this case. I found it in our legacy code; I just wanna make sure what I know!
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
Local references to objects are a bit different. The reference itself is not shared. The object referenced however, is not stored in each threads's local stack. All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.
Object members are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object members, the method is not thread safe.
Thread safety check: If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread,the use of that resource is thread safe.
From: http://tutorials.jenkov.com/java-concurrency/thread-safety.html
When I call test() in each thread, can I guarantee that test() is thread safe?
Yes it would be thread safe if in test() method you are working on
method local variables.
Where are the local varibles in test() stored? each threads' stack? heap space?
Method Local variable are stored each thread's own stack.
For number 1, I don't know what test() does, so I cannot answer. If they modify some static variable of the class A, then it may not be thread safe. If both threads along the way are given reference to the same object, depending on how the object is defined, it might not be thread safe.
For number 2, local variables are in the stack of each thread (or at least conceptually like that), so there is no worry about the local variables being modified by the other threads.
Lets say for example, a thread is creating and populating the reference variable of an immutable class by creating its object and another thread kicks in before the first one completes and creates another object of the immutable class, won't the immutable class usage be thread unsafe?
Creating an immutable object also means that all fields has to be marked as final.
it may be necessary to ensure correct behavior if a reference to
a newly created instance is passed from one thread to another without
synchronization
Are they trying to say that the other thread may re-point the reference variable to some other object of the immutable class and that way the threads will be pointing to different objects leaving the state inconsistent?
Actually immutable objects are always thread-safe, but its references may not be.
Confused?? you shouldn't be:-
Going back to basic:
Thread-safe simply means that two or more threads must work in coordination on the shared resource or object. They shouldn't over-ride the changes done by any other thread.
Now String is an immutable class, whenever a thread tries to change it, it simply end up creating a new object. So simply even the same thread can't make any changes to the original object & talking about the other thread would be like going to Sun but the catch here is that generally we use the same old reference to point that newly created object.
When we do code, we evaluate any change in object with the reference only.
Statement 1:
String str = "123"; // initially string shared to two threads
Statement 2:
str = str+"FirstThread"; // to be executed by thread one
Statement 3:
str=str+"SecondThread"; // to be executed by thread two
Now since there is no synchronize, volatile or final keywords to tell compiler to skip using its intelligence for optimization (any reordering or caching things), this code can be run in following manner.
Load Statement2, so str = "123"+"FirstThread"
Load Statement3, so str = "123"+"SecondThread"
Store Statement3, so str = "123SecondThread"
Store Statement2, so str = "123FirstThread"
and finally the value in reference str="123FirstThread" and for sometime if we assume that luckily our GC thread is sleeping, that our immutable objects still exist untouched in our string pool.
So, Immutable objects are always thread-safe, but their references may not be. To make their references thread-safe, we may need to access them from synchronized blocks/methods.
In addition to other answers posted already, immutable objects once created, they cannot be modified further. Hence they are essentially read-only.
And as we all know, read-only things are always thread-safe. Even in databases, multiple queries can read same rows simultaneously, but if you want to modify something, you need exclusive lock for that.
Immutable objects are thread safe, but why?
An immutable object is an object that is no longer modified once it has been constructed. If in addition, the immutable object is only made accessible to other thread after it has been constructed, and this is done using proper synchronization, all threads will see the same valid state of the object.
If one thread is creating populating the reference variable of the immutable class by creating its object and at the second time the other thread kicks in before the first thread completes and creates another object of the immutable class, won't the immutable class usage be thread unsafe?
No. What makes you think so? An object's thread safety is completely unaffected by what you do to other objects of the same class.
Are they trying to say that the other thread may re-point the reference variable to some other object of the immutable class and that way the threads will be pointing to different objects leaving the state inconsistent?
They are trying to say that whenever you pass something from one thread to another, even if it is just a reference to an immutable object, you need to synchronize the threads. (For instance, if you pass the reference from one thread to another by storing it in an object or a static field, that object or field is accessed by several threads, and must be thread-safe)
Thread safety is data sharing safety, And because in your code you make decisions based on the data your objects hold, the integrity and deterministic behaviour of it is vital. i.e
Imagine we have a shared boolean instance variable across two threads that are about to execute a method with the following logic
If flag is false, then I print "false" and then I set the flag back to true.
If flag is true, then I print "true" and then I set the flag back to false.
If you run continuously in a single thread loop, you will have a deterministic output which will look like:
false - true - false - true - false - true - false ...
But, if you ran the same code with two threads, then, the output of your output is not deterministic anymore, the reason is that the thread A can wake up, read the flag, see that is false, but before it can do anything, thread B wakes up and reads the flag, which is also false!! So both will print false... And this is only one problematic scenario I can think of... As you can see, this is bad.
If you take out the updates of the equation the problem is gone, just because you are eliminating all the risks associated with data sync. that's why we say that immutable objects are thread safe.
It is important to note though, that immutable objects are not always the solution, you may have a case of data that you need to share among different threads, in this cases there are many techniques that go beyond the plain synchronization and that can make a whole lot of difference in the performance of your application, but this is a complete different subject.
Immutable objects are important to guarantee that the areas of the application that we are sure that don't need to be updated, are not updated, so we know for sure that we are not going to have multithreading issues
You probably might be interested in taking a look at a couple of books:
This is the most popular: http://www.amazon.co.uk/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1?ie=UTF8&qid=1329352696&sr=8-1
But I personally prefer this one: http://www.amazon.co.uk/Concurrency-State-Models-Java-Programs/dp/0470093552/ref=sr_1_3?ie=UTF8&qid=1329352696&sr=8-3
Be aware that multithreading is probably the trickiest aspect of any application!
Immutability doesn't imply thread safety.In the sense, the reference to an immutable object can be altered, even after it is created.
//No setters provided
class ImmutableValue
{
private final int value = 0;
public ImmutableValue(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
}
public class ImmutableValueUser{
private ImmutableValue currentValue = null;//currentValue reference can be changed even after the referred underlying ImmutableValue object has been constructed.
public ImmutableValue getValue(){
return currentValue;
}
public void setValue(ImmutableValue newValue){
this.currentValue = newValue;
}
}
Two threads will not be creating the same object, so no problem there.
With regards to 'it may be necessary to ensure...', what they are saying is that if you DON'T make all fields final, you will have to ensure correct behavior yourself.
I was wondering if you have a static method that is not synchronised, but does not modify any static variables is it thread-safe? What about if the method creates local variables inside it? For example, is the following code thread-safe?
public static String[] makeStringArray( String a, String b ){
return new String[]{ a, b };
}
So if I have two threads calling ths method continously and concurrently, one with dogs (say "great dane" and "bull dog") and the other with cats (say "persian" and "siamese") will I ever get cats and dogs in the same array? Or will the cats and dogs never be inside the same invocation of the method at the same time?
This method is 100% thread safe, it would be even if it wasn't static. The problem with thread-safety arises when you need to share data between threads - you must take care of atomicity, visibility, etc.
This method only operates on parameters, which reside on stack and references to immutable objects on heap. Stack is inherently local to the thread, so no sharing of data occurs, ever.
Immutable objects (String in this case) are also thread-safe because once created they can't be changed and all threads see the same value. On the other hand if the method was accepting (mutable) Date you could have had a problem. Two threads can simultaneously modify that same object instance, causing race conditions and visibility problems.
A method can only be thread-unsafe when it changes some shared state. Whether it's static or not is irrelevant.
The function is perfectly thread safe.
If you think about it... assume what would happen if this were different. Every usual function would have threading problems if not synchronized, so all API functions in the JDK would have to be synchronized, because they could potentially be called by multiple threads. And since most time the app is using some API, multithreaded apps would effectively be impossible.
This is too ridiculous to think about it, so just for you: Methods are not threadsafe if there is a clear reason why there could be problems. Try to always think about what if there were multiple threads in my function, and what if you had a step-debugger and would one step after another advance the first... then the second thread... maybe the second again... would there be problems? If you find one, its not thread safe.
Please be also aware, that most of the Java 1.5 Collection classes are not threadsafe, except those where stated, like ConcurrentHashMap.
And if you really want to dive into this, have a close look at the volatile keyword and ALL its side effects. Have a look at the Semaphore() and Lock() class, and their friends in java.util.Concurrent. Read all the API docs around the classes. It is worth to learn and satisfying, too.
Sorry for this overly elaborate answer.
Use the static keyword with synchronized static methods to modify static data shared among threads. With the static keyword all the threads created will contend for a single version of the method.
Use the volatile keyword along with synchronized instance methods will guarantee that each thread has its own copy of the shared data and no read/ writes will leak out between threads.
String objects being immutable is another reason for thread-safe scenario above. Instead if mutable objects are used (say makeMutableArray..) then surely thread-safety will break.
Since the complete method was pushed onto the stack, any variable creation that takes place lives within the stack (again exceptions being static variables) and only accessible to one thread. So all the methods are thread safe until they change the state of some static variable.
See also:
Is static method is thread safe in Java?