Does volatile propagate to instance members? - java

Suppose there is some simple container declared and instantiated like this
class Test {
private volatile List<Object> list = new ArrayList<>();
}
, and reads and writes to it are guarded by locks; synchronized keyword not used. Although Test.list is declared volatile, none of its member fields like ArrayList.elementData also bear this modifier. Now, in multithreaded application, will it behave like volatile container? In other words, will changes submitted to ArrayList.elementData by some thread be visible immediately by all other threads?

The general answer is no: volatile only establishes a happens-before relationship between reads and writes to the reference variable. If two threads concurrently access an inner field of the object referenced in the variable, there still needs to be a synchronization mechanism.
In your case, the best approach seems to use a synchronized list, or some wrapper from the java.util.concurrent package.

Short answer: no. As a consequence, array elements are always non-volatile (even if the array itself is declared volatile). You need to use special concurrent-friendly implementation of the List. Usually java.util.concurrent.CopyOnWriteArrayList fits the needs. If you assign the list variable only once, then volatile keyword does not change anything (in this case better to use final).

Related

It is required synchronized keyword for non void method?

If method have return type and it is access by two or more thread then it is required to use synchronized block or keyword with this method?
No. If that method does changes any of the field of the object that its operating upon (i.e. changing the state of object) and same object is shared amongst two thread then you might need it.
You may need to use synchronized when you are reading fields which can be changed in another thread, or writing fields which might be read in another thread. There is no specific rule of when you must, or must not use synchronized or the language would be able to do this for you. It is up to you to decide based on you use case.
It is not required. For example, if your class does not offer methods which modify instances of this class (then the class is said to be immutable) you don't need to synchronize.
However, as soon as at least one thread can write to some member variable, and there exist other threads which can read from or write to this variable at the same time, you need to synchronize the access to this variable, either by using the synchronized keyword or by manipulating locks explicitly. In some cases, you might also use atomic operation (AtomicInteger, for example).

Difference between class locking and object locking in Java

People tell about two types of multi-threaded locking - object and class. In my knowledge, locking is done on objects only.
Case 1: On objects we create using new or factory methods etc.
void synchronized myMethod(Type param) {
//will lock on the instance used to call this method
}
or
synchronized(this) {
//will lock on current object
}
or
synchronized(obj1) {
//will lock on specified obj1 object
}
Case 2: On java.lang.Class objects
This is called class lock, and can be used with static fields or methods or blocks, as they belong to class and shared among all the objects, and other class properties.
static void synchronized method() {
//will lock the Class object
}
or
static {
synchronized(SomeClass.class){
int a = 2;
}
}
Why I am thinking this also as an object locking because classes are loaded into the Method Area in the JVM, and all the static properties of the class are wrapped inside a java.lang.Class object created by JVM. So behind abstraction, its object locking and in the picture, we see Class locking.
So I can also infer one more thing. Just as objects locked by a thread can not be acquired by another thread as long as it is not released by first thread, class locking (the java.lang.Class instance) also works in same manner.
I want to know in case of synchronized static methods, lock on which class is acquired by the thread in following two cases:
This method is called from same class where it is defined.
This method is called from derived class with derived class name.
This is my understanding so far regarding the subject. Please add on or rectify.
People tell about two types of multi-threaded locking - object and class.
A Class is an Object. There is only one kind of locking in the Java language: Every Object (including every Class) has a mutex that can be locked by a synchronized block or a synchronized method. The Object to be locked is implicit in a synchronized method: It's the "this" instance for an instance method, and it's the Class object for a static method.
One of the most common newbie mistakes is to think that two different threads can't get into the same synchronized block at the same time. They can, and there's plenty of questions and answers here in StackOverflow that prove it. Another mistake is to think that if one thread is synchronized on some object, then other threads will not be able to modify the object. They can and they do.
Synchronization prevents two or more threads from synchronizing on the same Object at the same time. Which object is the right object? It's all about protecting your data. If the structure that you want to protect is a linked list, for example, then a good choice would be for any method that accesses the list to synchronize on the list header. If you want to protect global data (e.g., static variables), then you want to synchronize on a global object (e.g., the Class object that owns the variables.) The important thing is that, if you have read/write data (a.k.a., "mutable data") that are accessed by more than one thread, then every method that accesses the same data must synchronize on the same lock.
There is another kind of locking in Java, but it's not in the Java language; it's in the Java standard library. It's available through objects that implement the java.util.concurrent.locks.Lock interface. Of course a Lock object (like any Object) also implements the first kind of locking, but you should never, ever, synchronize on a Lock object unless you want to give people the impression that you are a clueless newbie.
The java.util.concurrent-style locking is more powerful than using synchronized blocks because of it's explicit lock() and unlock() methods. For example, it is possible for one method to lock a lock, and a different method to unlock it. That can lead to code that is tricky to understand, and I wouldn't do it unless I had a very good reason, but sometimes there are good reasons.
The only difference is that a static synchronized locks on the class instance and a non-static synchronized method locks on the instance.
People tell about two types of multi-threaded locking
There is object instance locks and Lock style locks. A Lock, confusingly, has both.
object and class
Not true as you have worked out already.
Just because people say stuff doesn't make it true. Often people say a lot of nonsense. In fact there is whole web sites devoted to non-sense about Java. :P

Are class variables in Java shared between threads or not?

I was wondering when declaring a class variable (i.e. a variable declared outside a method) would potentially cause problems in a program that's executed by several threads. I suppose finals are save to use (i.e. not shared), and static variables are definitely shared between threads. But what about "standard" variables? When are they shared and when are they "private" to each individual thread?
Update: While I accept that local variables (within methods) are not shared and class variables usually are I would love to understand why that is (from a technical point of view). So any explanation to that effect (or links to articles that are fairly easy to understand) would be much appreciated.
Java provides the ThreadLocal<T> class to declare variables that are not shared between threads. Non-final parameters and local variables are also not shared between threads. final parameters and locals variables may be shared between threads when they are used in an anonymous class definition, but this shouldn't be a problem since they are final. In all other cases I can think of, variables can be shared between threads.
The short answer is, any method or variable, both static and non-static, has the potential to be accessed by more than one Thread if its access modifier makes it visible to that Thread.
The concept of "thread-safe" is entirely different. If a variable is read-only (final can be used to make primitives read-only, but only makes references to objects immutable, not the objects themselves), multi-threaded access of that variable is inherently thread-safe. If it can be written to, the proper use of synchronized blocks or the volatile keyword is necessary to ensure mutual exclusion.
There's nothing special about a standard variable that shields it from multi-threaded access and resulting problems. That's up to YOU the programmer to worry about.
If two threads need to safely access the same instance fields, then YOU have to write code to manage that.
Some common techniques are to use synchronized blocks to manage mutability, using atomic or final primitives (a final Object is not necessarily safe unless you know the Object isn't mutable), or simply use a ThreadLocal to give each thread its own unshared instance of the class.
Final doesn't mean 'not shared' just that the field cannot be overwritten, it can only be initialized one.
Static behavior is also not related to threading, static means that the field has a Class scope and not instance scope, meaning it's shared by all the instances of a Class.
If you want to protect a field from being modified by many threads, you have to manipulate it through synchronized methods.
Such variables are called the fields of the class, and they are definitely not "thread-safe" in general, even when they are final (because final only refers to the reference itself, not what's inside the object).

In Java, do methods that don't use static or class variables need to be synchronized?

Do methods that only use local variables inside suffer any threading issues ?. Somewhere it was mentioned that the method with local variables are copied to each thread stack frame to work with and do not need to synchronized for multithreaded implementation unless it uses class level or static references/variables ?
If your method only operates on parameters and locally-defined (as opposed to class member) variables then there are zero synchronization problems to worry about.
But...
This means any mutable reference types you use must live and die only within the scope of your method. (Immutable reference types aren't a problem here.) For example this is no problem:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
return working_set.doSomethingElseAgain(interim);
}
A MyObject instance is created within your method, does all of its work in your method and is coughing up blood, waiting to be culled by the GC when you exit your method.
This, on the other hand, can be a problem:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
another_interim = doSomethingSneaky(working_set);
return working_set.doSomethingElseAgain(another_interim);
}
Unless you know for sure what's going on in doSomethingSneaky(), you may have a need for synchronization somewhere. Specifically you may have to do synchronization on the operations on working_set because doSomethingSneaky() could possibly store the reference to your local working_set object and pass that off to another thread while you're still doing stuff in your method or in the working_set's methods. Here you'll have to be more defensive.
If, of course, you're only working with primitive types, even calling out to other methods, passing those values along, won't be a problem.
Does methods that only use local variables inside, do not suffer any threading issues ?
True in a very simplistic sense, but lets be clear - I think this is only true if:
such a method uses only local variables that are primitives or references to mutable instances that cannot otherwise be accessed outside the method by any other means.
such a method invokes only methods that are thread-safe.
Some ways these rules could be violated:
A local variable could be initialized to point to an object that is also accessible outside the method. For example, a local variable could point to a singleton (Foo bar = Foo.getSingleton()).
A local instance held by a local variable could "leak" if the instance is passed as a argument to an external method that keeps a reference to the instance.
A class with no instance variables and with only a single method with no local variables could still call the static method of another class that is not thread-safe.
The question is very generic, so please do not expect any specificity from my answer.
1_ We need to more careful with static methods than say instance methods.
2_ #Justmycorrectopinion is about right, but some of the terms he described needs to be more elaborated to be perfect. ( Even if the static method, only works on local variable, there is still possibility of race condition.)
3_ For me there are simple rules that have helped me analyze thread safety.
Understand if each components encapsulated within it is shareable or not. So the simplest solution is to reduce the scope of all variable and only increase scope if absolutely necessary and if component perform mutation on a object, its usually not thread safe.
4_ Use tooling support to perform static code analysis on thread safety. (Idea has checkthread plugin).
5_ Never use static method to perform object mutation. If calling static variable causes object mutation, then the developer is just circumventing OOPS.
6_ Always document thread safety. Remember some method may not need to be synchronized when you develop, but can be made not thread safe very easily.
7_ Last but probably my most important point, make sure most of your objects are immutable. In my experience, most of the time, I never had to make many of my objects mutable. (In rare cases when object state needs to be changed, defensive copying / New Object Creation is almost always better. )
You do not need to worry about local variables. Instance variables however are something to care about.

What does using volatile when using a java.util.concurrent.Concurrent* containers provide?

The question came up when I saw this code:
private static volatile ConcurrentHashMap<String, String> cMap = null;
static {
cMap = new ConcurrentHashMap<String, String>();
}
To me it looks like the volatile there is redundant as the container is ConcurrentHashMap which according the JavaDoc already has synchronized puts, DUH, the class that uses the cMap only instantiates it once and doesn't have any methods of setting or getting it.
The only thing I see volatile providing here is that if I would be setting the cMap to reference a new object in near future, those reads and writes would be synchronized.
Am I missing something?
The volatile modifier doesn't have anything to do with the class involved - it's only to do with the variable cMap. It only affects how a thread fetches or changes the value of that variable. By the time you've got as far as invoking methods on the referenced object, you've gone beyond the bailiwick of volatile.
As you say, it basically makes sure that all threads would be guaranteed to see changes to the cMap value (i.e. making it refer to a different map).
That may be a good idea - or it may not, depending on what the rest of the code does. If you could make it final for example, you wouldn't need it to be volatile...
unless the variable is re-assigned later, the volatile is totally unnecessary.
any writes occurred in the static initializer are visible to any code using the class (i.e. when a static method/field is accessed, when a constructor is invoked)
without that guarantee, we are in deep trouble. millions lines of code would be wrong.
see JLS3 $12.4.2:
The procedure for initializing a class
or interface is then as follows:
Synchronize (ยง14.19) on the Class object that represents the class
or interface to be initialized.
Declaring the cMap reference as volatile ensures that its initialized value is visible to all threads. AFAIK without this, it is not guaranteed, i.e. some threads might see a null reference instead of the reference to a properly initialized map object.
[Update] As #irreputable pointed out (and as is explained in Java Concurrency in Practice, section 3.5.3), I was wrong with the above statement: static initializers are indeed executed by the JVM at class initialization time, guarded by internal synchronization of the JVM. So volatile is not necessary.[/Update]
OTOH declaring it final (and initializing it straight away, not in a separate static block) would guarantee visibility too.
Note that the reference being volatile or not has nothing to do with the class of the variable it refers to. Even if the referred class is threadsafe, the reference itself may not be.
You would declare cMap volatile only when its value changes. Declaring it volatile says nothing about the objects held in the map.
If cMap changes all threads will need to see the new up to date value of the CHM. That being said, I would highly recommend cMap being final. A non final static variable can be dangerous.

Categories

Resources