I'm confused by an issue about reference and synchronized keyword a long time.
I usually see some code like this:
Class someClass {
...
private SomeObject mObject;
...
public void someMethod() {
...
final SomeObject obj = mObject;
...
//then use the 'obj' variable rather than mObject
...
}
}
My question is why should use local final variable obj to replace the member variable?
Why not use the member variable directly?
I also see some example code associated with 'synchronized' keyword,like this:
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
Why these code can achieve the synchronized goal?
Thanks!
From what I can understand of your question and the first example, the code is trying to avoid threading problems by wanting to take a local copy of the member variable. The first example doesn't do this, it just gets a new local variable pointing to the same object the member variable points to, but doesn't actually protect invokations on that object from threading issues.
Edit following #Nick's comment: like Nick says, the first example's someMethod method avoids the possibility of having the mObject being replaced by another instance half way through. It doesn't however protect against threading issues by concurrent invokations on the same instance.
1>
I think for ur first question...member variable is not used directly because that reference object can be used in some other methods as well....and in other methods it may not be required to be declared as final as in case of the method as u have shown....so it is good practice to create a local reference of that variable.....
2>
Suppose some reference object is being accessed concurrently using threads....now if that object modifies some data then for concurrent access integrity of that data is lost....so it is required that there is some kind of lock on that object reference so that while one thread is accessing one of the reference of that object some other thread should not be able to access it....so this synchronized keyword is used to achieve just that...
In the first example, I believe the idea is to take a copy of the member variable in a final local variable so that if the member variable is changed on another thread, the copy in the member function will remain the same.
The second example is similar in that it's taking a copy of the currently connected thread in a local variable.
Imagine in either case if the member variable (or connected thread) were accessed directly and then changed part way through the function call by another thread, undefined behaviour may occur.
I'm sure there's a name for this coding pattern but I can't remember it!
As far as the first question is concerned it's making sure that the method can't modify the object, by aliasing it to a final variable you're ensuring you're not reassigning something later? I'm not sure...
The second question:
this works because if mState is not connected then we return from the method and r.write() doesn't get executed. It uses the object itself as a lock.
Related
public class Test{
private MyObj myobj = new MyObj(); //it is not volatile
public class Updater extends Thred{
myobje = getNewObjFromDb() ; //not am setting new object
}
public MyObj getData(){
//getting stale date is fine for
return myobj;
}
}
Updated regularly updates myobj
Other classes fetch data using getData
IS this code thread safe without using volatile keyword?
I think yes. Can someone confirm?
No, this is not thread safe. (What makes you think it is?)
If you are updating a variable in one thread and reading it from another, you must establish a happens-before relationship between the write and the subsequent read.
In short, this basically means making both the read and write synchronized (on the same monitor), or making the reference volatile.
Without that, there are no guarantees that the reading thread will see the update - and it wouldn't even be as simple as "well, it would either see the old value or the new value". Your reader threads could see some very odd behaviour with the data corruption that would ensue. Look at how lack of synchronization can cause infinite loops, for example (the comments to that article, especially Brian Goetz', are well worth reading):
The moral of the story: whenever mutable data is shared across threads, if you don’t use synchronization properly (which means using a common lock to guard every access to the shared variables, read or write), your program is broken, and broken in ways you probably can’t even enumerate.
No, it isn't.
Without volatile, calling getData() from a different thread may return a stale cached value.
volatile forces assignments from one thread to be visible on all other threads immediately.
Note that if the object itself is not immutable, you are likely to have other problems.
You may get a stale reference. You may not get an invalid reference.
The reference you get is the value of the reference to an object that the variable points to or pointed to or will point to.
Note that there are no guarantees how much stale the reference may be, but it's still a reference to some object and that object still exists. In other words, writing a reference is atomic (nothing can happen during the write) but not synchronized (it is subject to instruction reordering, thread-local cache et al.).
If you declare the reference as volatile, you create a synchronization point around the variable. Simply speaking, that means that all cache of the accessing thread is flushed (writes are written and reads are forgotten).
The only types that don't get atomic reads/writes are long and double because they are larger than 32-bits on 32-bit machines.
If MyObj is immutable (all fields are final), you don't need volatile.
The big problem with this sort of code is the lazy initialization. Without volatile or synchronized keywords, you could assign a new value to myobj that had not been fully initialized. The Java memory model allows for part of an object construction to be executed after the object constructor has returned. This re-ordering of memory operations is why the memory-barrier is so critical in multi-threaded situations.
Without a memory-barrier limitation, there is no happens-before guarantee so you do not know if the MyObj has been fully constructed. This means that another thread could be using a partially initialized object with unexpected results.
Here are some more details around constructor synchronization:
Constructor synchronization in Java
Volatile would work for boolean variables but not for references. Myobj seems to perform like a cached object it could work with an AtomicReference. Since your code extracts the value from the DB I'll let the code stay as is and add the AtomicReference to it.
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
private AtomicReference<MyObj> myobj = new AtomicReference<MyObj>();
public class Updater extends Thread {
public void run() {
MyObj newMyobj = getNewObjFromDb();
updateMyObj(newMyobj);
}
public void updateMyObj(MyObj newMyobj) {
myobj.compareAndSet(myobj.get(), newMyobj);
}
}
public MyObj getData() {
return myobj.get();
}
}
class MyObj {
}
Here is a question that has been asked many times, I have double-checked numerous issues that have been raised formerly but none gave me an answer element so I thought I would put it here.
The question is about making my code thread-safe in java knowing that there is only one shared variable but it can change anytime and actually I have the feeling that the code I am optimizing has not been thought for a multi-threading environment, so I might have to think it over...
Basically, I have one class which can be shared between, say, 5 threads. This class has a private property 'myProperty' which can take 5 different values (one for each thread). The problem is that, once it's instantiated by the constructor, that value should not be changed anymore for the rest of the thread's life.
I am pretty well aware of some techniques used to turn most of pieces of code "thead-safe" including locks, the "synchronized" keyword, volatile variables and atomic types but I have the feeling that these won't help in the current situation as they do not prevent the variable from being modified.
Here is the code :
// The thread that calls for the class containing the shared variable //
public class myThread implements Runnable {
#Autowired
private Shared myProperty;
//some code
}
// The class containing the shared variable //
public class Shared {
private String operator;
private Lock lock = new ReentrantLock();
public void inititiate(){
this.lock.lock()
try{
this.operator.initiate() // Gets a different value depending on the calling thread
} finally {
this.lock.unlock();
}
}
// some code
}
As it happens, the above code only guarantees that two threads won't change the variable at the same time, but the latter will still change. A "naive" workaround would consist in creating a table (operatorList) for instance (or a list, a map, etc. ) associating an operator with its calling thread's ID, this way each thread would just have to access its operator using its id in the table but doing this would make us change all the thread classes which access the shared variable and there are many. Any idea as to how I could store the different operator string values in an exclusive manner for each calling thread with minimal changes (without using magic) ?
I'm not 100% sure I understood your question correctly, but I'll give it a shot anyway. Correct me if I'm wrong.
A "naive" workaround would consist in creating a table (operatorList)
for instance (or a list, a map, etc. ) associating an operator with
its calling thread's ID, this way each thread would just have to
access its operator using its id in the table but doing this would
make us change all the thread classes which access the shared variable
and there are many.
There's already something similar in Java - the ThreadLocal class?
You can create a thread-local copy of any object:
private static final ThreadLocal<MyObject> operator =
new ThreadLocal<MyObject>() {
#Override
protected MyObject initialValue() {
// return thread-local copy of the "MyObject"
}
};
Later in your code, when a specific thread needs to get its own local copy, all it needs to do is: operator.get(). In reality, the implementation of ThreadLocal is similar to what you've described - a Map of ThreadLocal values for each Thread. Only the Map is not static, and is actually tied to the specific thread. This way, when a thread dies, it takes its ThreadLocal variables with it.
I'm not sure if I totally understand the situation, but if you want to ensure that each thread uses a thread-specific instance for a variable, the solution is use a variable of type ThreadLocal<T>.
As I am trying to get to grips with thread safety, I would like to know if this class is threadsafe? If two threads try to access its variables at any time it seems to me that it is thread safe because:
final variable is threadsafe by virtue of being immutable.
getter and setter are synchronized, so mObject can only be gotten, or set by one thread at a time. So there is no chance of two threads reading different values.
The method changeObj() is not synchronized but any block in it which deals with class variables (i.e. mObject) is synchronized.
Please tell me if I am wrong or if this class is not threadsafe.
public class MyClass{
private final String = "mystring"; //thread safe because final
private AnObject mObject;
public MyClass(){
//initialize
}
//only one class can set the object at a time.
public synchronized void setObj(AnObject a){
mObject = a;
}
//two threads trying to get the same object will not read different values.
public synchronized AnObject getObj(){
return mObject;
}
//better to synchronize the smallest possible block than the whole method, for performance.
public void changeObj(){
//just using local variables (on stack) so no need to worry about thread safety
int i = 1;
//i and j are just to simulate some local variable manipulations.
int j =3;
j+=i;
synchronized(this){
//change values is NOT synchronized. Does this matter? I don't think so.
mObject.changeValues();
}
}
}
No, it's not thread safe. You make sure only one thread can change the values in your AnObject at a time if it uses the changeObj() method, but you also provide a getter for this object, so any other thread could call changeValues() concurrently.
Your class in itself is thread safe in its current state (assuming any methods not shown here are), however you have one likely "bug" in your thinking;
mObject isn't 100% encapsulated, it is passed in through a setter and can be fetched through a getter. That means that any thread could get a reference to and call methods on the object referenced by mObject simultaneously without MyClass knowing about it.
In other words, AnObject's methods may need to be thread safe too.
At the very least, the synchronizing in MyClass doesn't in any way make mObject safe from threading problems.
Adding to Mr. JB Nizet's points, if AnObject.changeValues is a method that is designed to be overridden by clients, or calls such methods, then this, in the general case, opens the door for various unwanted behaviours, like deadlocks and data corruption. You must never cede control to alien code within a synchronized block. By "alien" I mean code not under your control. More details can be found in Effective Java, 2nd Ed, Item 67.
A final variable is not necessarily thread safe, only immutable final variables are thread safe -- that covers primitives and classes like String, or final variables of classes which themselves are thread-safe.
Your class is not thread safe because it exposes the variable a, but also requires it for its internal working.
The below example will demonstrate an example of how a could get into an inconsistent state.
Thread A
MyClass myClass = ...
myClass.changeObj();
// imagine Thread A is suspended during the synchronized block inside of
// changeObj()
Thead B
MyClass myClass = ...
AnObj anObj = myClass.getObj();
anObj.changeValues();
// uh-oh, I am modifying the state of this instance of anObj which is also
// currently being modified by Thread A
For MyClass to be truly thread safe you must do one of the following.
AnObj must also guarantee thread safety (by making methods that modify its state thread-safe)
AnObj must be immutable. That is, if you need to modify the state of AnObj you must create new instance of AnObj to hold the new state.
The getter for AnObj must not directly expose MyClass's instance of AnObj, but a rather return a copy of that instance.
I have a doubt on the java synchronization mechanism. Let us take the following piece of code--
class A {
int instance=0;
synchronized void met1() {
instance=instance +1;
....
instance = instance+2*3;
}
In the above method met1, we need to make it synchronized in a multi threaded enviroment because it is modifying an instance variable of an object. However in this piece of code --
class A {
synchronized void met1() {
local=local +1;
....
local = local+2*3;
}
The method met1 is modifying a local variable, which I think will be unique for each thread that executes that method. So in this case, when a thread is modifying only a local variable, is it necessary to make the method synchronized ?
Assuming the variable is declared inside met1, no, you don't need synchronized.
In your second example, local is not exactly local, because you are not declaring it inside met1. Probably you meant:
synchronized void met1() {
int local = 0;
// ...
local=local +1;
....
local = local+2*3;
}
Then yes, you are correct, since each method call happens on the stack of the calling thread, method-local variables exist only the corresponding thread's stack and don't need synchronized access.
Not if the variable is truly method-local -- however, your example code doesn't actually show the local declaration! So don't spread this example around...
No, if a method defines and uses variables in local scope only, you don't need to synchronize it. You only need to synchronize those methods which either change or provide access to mutable state.
Java concurrency rules are more complicated than you might think and there are plenty of gotchas so it's well worth reading up on the intricacies. "Java Concurrency in Practice" by Goetz et al is pretty good (and is basically from the horses mouth).
No. If the method only modifies local variables and method arguments, you don't need to synchronize the method. The more stateless and immutable your classes are, the less synchronization you need.
Nope, is is not necessary to sync a method which , only modifies local variables and does not alter the state of objects
You don't need to worry about local variables in multi threaded environment. You don't need to make it synchronized . But In your code the variable "local" is not defined as local variable in met1().
I recently wrote a class for an assignment in which I had to store names in an ArrayList (in java). I initialized the ArrayList as an instance variable private ArrayList<String> names. Later when I checked my work against the solution, I noticed that they had initialized their ArrayList in the run() method instead.
I thought about this for a bit and I kind of feel it might be a matter of taste, but in general how does one choose in situations like this? Does one take up less memory or something?
PS I like the instance variables in Ruby that start with an # symbol: they are lovelier.
(meta-question: What would be a better title for this question?)
In the words of the great Knuth "Premature optimization is the root of all evil".
Just worry that your program functions correctly and that it does not have bugs. This is far more important than an obscure optimization that will be hard to debug later on.
But to answer your question - if you initialize in the class member, the memory will be allocated the first time a mention of your class is done in the code (i.e. when you call a method from it). If you initialize in a method, the memory allocation occurs later, when you call this specific method.
So it is only a question of initializing later... this is called lazy initialization in the industry.
Initialization
As a rule of thumb, try to initialize variables when they are declared.
If the value of a variable is intended never to change, make that explicit with use of the final keyword. This helps you reason about the correctness of your code, and while I'm not aware of compiler or JVM optimizations that recognize the final keyword, they would certainly be possible.
Of course, there are exceptions to this rule. For example, a variable may by be assigned in an if–else or a switch. In a case like that, a "blank" declaration (one with no initialization) is preferable to an initialization that is guaranteed to be overwritten before the dummy value is read.
/* DON'T DO THIS! */
Color color = null;
switch(colorCode) {
case RED: color = new Color("crimson"); break;
case GREEN: color = new Color("lime"); break;
case BLUE: color = new Color("azure"); break;
}
color.fill(widget);
Now you have a NullPointerException if an unrecognized color code is presented. It would be better not to assign the meaningless null. The compiler would produce an error at the color.fill() call, because it would detect that you might not have initialized color.
In order to answer your question in this case, I'd have to see the code in question. If the solution initialized it inside the run() method, it must have been used either as temporary storage, or as a way to "return" the results of the task.
If the collection is used as temporary storage, and isn't accessible outside of the method, it should be declared as a local variable, not an instance variable, and most likely, should be initialized where it's declared in the method.
Concurrency Issues
For a beginning programming course, your instructor probably wasn't trying to confront you with the complexities of concurrent programming—although if that's the case, I'm not sure why you were using a Thread. But, with current trends in CPU design, anyone who is learning to program needs to have a firm grasp on concurrency. I'll try to delve a little deeper here.
Returning results from a thread's run method is a bit tricky. This method is the Runnable interface, and there's nothing stopping multiple threads from executing the run method of a single instance. The resulting concurrency issues are part of the motivation behind the Callable interface introduced in Java 5. It's much like Runnable, but can return a result in a thread-safe manner, and throw an Exception if the task can't be executed.
It's a bit of a digression, but if you are curious, consider the following example:
class Oops extends Thread { /* Note that thread implements "Runnable" */
private int counter = 0;
private Collection<Integer> state = ...;
public void run() {
state.add(counter);
counter++;
}
public static void main(String... argv) throws Exception {
Oops oops = new Oops();
oops.start();
Thread t2 = new Thread(oops); /* Now pass the same Runnable to a new Thread. */
t2.start(); /* Execute the "run" method of the same instance again. */
...
}
}
By the end of the the main method you pretty much have no idea what the "state" of the Collection is. Two threads are working on it concurrently, and we haven't specified whether the collection is safe for concurrent use. If we initialize it inside the thread, at least we can say that eventually, state will contain one element, but we can't say whether it's 0 or 1.
From wikibooks:
There are three basic kinds of scope for variables in Java:
local variable, declared within a method in a class, valid for (and occupying storage only for) the time that method is executing. Every time the method is called, a new copy of the variable is used.
instance variable, declared within a class but outside any method. It is valid for and occupies storage for as long as the corresponding object is in memory; a program can instantiate multiple objects of the class, and each one gets its own copy of all instance variables. This is the basic data structure rule of Object-Oriented programming; classes are defined to hold data specific to a "class of objects" in a given system, and each instance holds its own data.
static variable, declared within a class as static, outside any method. There is only one copy of such a variable no matter how many objects are instantiated from that class.
So yes, memory consumption is an issue, especially if the ArrayList inside run() is local.
I am not completely I understand your complete problem.
But as far as I understand it right now, the performance/memory benefit will be rather minor. Therefore I would definitely favour the easibility side.
So do what suits you the best. Only address performance/memory optimisation when needed.
My personal rule of thumb for instance variables is to initialize them, at least with a default value, either:
at delcaration time, i.e.
private ArrayList<String> myStrings = new ArrayList<String>();
in the constructor
If it's something that really is an instance variable, and represents state of the object, it is then completely initialized by the time the constructor exits. Otherwise, you open yourself to the possibility of trying to access the variable before it has a value. Of course, that doesn't apply to primitives where you will get a default value automatically.
For static (class-level) variables, initialize them in the declaration or in a static initializer. I use a static initializer if I have do calculations or other work to get a value. Initialize in the declaration if you're just calling new Foo() or setting the variable to a known value.
You have to avoid Lazy initialization. It leads to problems later.
But if you have to do it because the initialization is too heavy you have to do it like this:
Static fields:
// Lazy initialization holder class idiom for static fields
private static class FieldHolder {
static final FieldType field = computeFieldValue();
}
static FieldType getField() { return FieldHolder.field; }
Instance fields:
// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) { // First check (no locking)
synchronized(this) {
result = field;
if (result == null) // Second check (with locking)
field = result = computeFieldValue();
}
}
return result;
}
Acording to Joshua Bolch book's "Effective Java™
Second Edition" (ISBN-13: 978-0-321-35668-0):
"Use lazy initialization judiciously"