How long do my static variables live? - java

I have a class that looks like:
public class BadCodeStyle {
private static String theAnswer = null;
public static void setAnswer(String whatsNew) {
theAnswer = whatsNew;
}
public static String getAnswer() {
return (theAnswer == null) ? "I don't know" : theAnswer;
}
}
Of course that's a simplification of the actual class. What really happens is that the static method retrieves a framework object if the variable is null. Setting the variable just serves to insert a mock value for test runs where I want to isolate the code from the framework (retrofitting code for testability is fun - like poking your own eye type of fun).
When I do BadCodeStyle.setAnswer("42") the static method behaves like a Singleton (?). I did read the classloader explanation and conclude: the variable will stay as long as the class is loaded and that would be as long as the JVM runs? Is that correct?

Static class variables live as long as the class definition is loaded. This is usually until the VM exits. However, there are other ways a class can be unloaded. See, for example, this thread and this one.

Static variables are common to all objects (shared) more precisely. it doesn't belong to any instance of class (objects). so its obvious that it cannot be garbage collected with objects.
class X
{
static string str;
}
X obj1 = new X();
X obj2 = new X();
when you define X.str compiler 'll say replace with Class reference.
But it belongs to Class object. we refer to it as Class variable too. (classloader loads the class)
so its single variable (singleton 's actually a pattern that uses single object [use private constructors and using a method to return that single object] )
As you read the memory is reclaimed only when the program is done. it doesn't get (reclaimed) garbage collected in between [Non used objects 'll be garbage collected normally] .
so its lifetime exists as long as the process exists [program is running].
checkout lifetime of variables: www.cs.berkeley.edu/~jrs/4/lec/08

Related

Is this code thread-safe or is using a parameter to synchronize risky? [duplicate]

Take this code:
public class MyClass {
private final Object _lock = new Object();
private final MyMutableClass _mutableObject = new MyMutableClass()
public void myMethod() {
synchronized(_lock) { // we are synchronizing on instance variable _lock
// do something with mutableVar
//(i.e. call a "set" method on _mutableObject)
}
}
}
now, imagine delegating the code inside myMethod() to some helper class where you pass the lock
public class HelperClass {
public helperMethod(Object lockVar, MyMutableClass mutableVar) {
synchronized(lockVar) { // we are now synchronizing on a method param,
// each thread has own copy
// do something with mutableVar
// (i.e. call a "set" method on mutableVar)
}
}
}
can "myMethod" be re-written to use the HelperClass by passing its lock var, so that everything is still thread safe? i.e.,
public void myMethod() {
_helperObject.helperMethod(_lock, _mutableObject);
}
I am not sure about this, because Java will pass the lockVar by value, and every thread will get a separate copy of lockVar (even though each copy points to the same object on the heap). I guess the question comes down to how 'synchronized' keyword works -- does it lock on the variable, or the value on the heap that the variable references?
Synchronization is done upon objects, not variables.
Variables/members [sometimes] contain objects and it is the resulting object contained in [variable] x that is actually synchronized upon in synchronized(x).
There are a few other issues with thread-visibility of variables (e.g. might read a "stale" object from a variable), but that does not apply here: there is no re-assignment of _lock and the visibility of the initial ("final") assignment is guaranteed. Because of this it is guaranteed that, in this case, the method parameter will always contain the correct (same) object used for the synchronization.
If the lock object used (where presumably _lock is not final) changes, however, then that would require re-evaluation of the appropriate values/thread-visibility but otherwise does not differ from any cross-thread access.
Happy coding.

Why we do not create object for static method in java?

Sometimes we call className.methodName() without creating object for it, I mean without using syntax as className objectName = new constructor() and then call as object.methodName()
When to use className.methodName()?
When to call method using object as object.methodName()?
Explanation of above two cases with example will be appreciated.
What you're referring to is a static method.
Assume that I have this :
public class A {
public static void foo(){
System.out.println("Hooray! I work!");
}
}
You can now do this anywhere else in any other class :
A.foo();
This is because the method is static, which means that it can be called on by the CLASS.
This means that it doesn't require an instance of that class in order for the method to be called.
However, even though it isn't required, you can still do this :
A a = new A();
a.foo();
But since the method foo() is static, instantiating an object A is not required in order to run the foo() method.
First. When you're create at least one static method of a class, you can use this method without creating an instance of class. This is useful, for example, for the creation of methods with independent logic. For example:
public class Checker {
public static Boolean month(int value) {
return (value >= 1 && value <= 12);
}
}
You need check correct value of month many times. But what to do each time to create the object. It is much effective to use a static method.
Second. When you create the object, the object is stored in the memory and you get a link to it. Then the object can be used for example to save at the list.
Method at this object is specific. You can save class data and do specific operation with member of this class. For example:
List<Animals> animalsList = new ArrayList<>();
Animal animal = new Animal("dog");
int legs = animal.getCountLegs(); // specific function for object
animalList.add(animal); //save if you need
// use list of object
For every class, we have a Object called as class object which is YourClass.class object. static methods are invoked based on meta-data on those objects. For instances of a class, methods are invoked on the actual instances. Both static and non-static methods are present on method area.
There is no different between 1 and 2 point, because in during compilation compiler makes ClassName.staticMethod() instead of instance.staticMethod().
Static methods in java belong to the class (not an instance of it). They use no instance variables and will usually take input from the parameters, perform actions on it, then return some result. Instances methods are associated with objects and, as the name implies, can use instance variables.

Singleton pattern interview

I am recently asked about java related question in an interview with following code, since I am very new to java and barely code in Java so I really have no idea what the following code does.
The question was
Select the option that describes the worst thing with the following code:
public class Bolton {
private static Bolton INST = null;
public static Bolton getInstance()
{
if ( INST == null )
{
INST = new Bolton();
}
return INST;
}
private Bolton() {
}
}
Here are the options for this question
More than one instance of Bolton can be created
A Bolton will never be created
The constructor is private and can't be called
Value can be garbage collected, and the call to getInstance may return garbage data
Which of the above options is correct? And Why?
This is a Singleton Pattern
The idea of a Singleton Pattern is to only have one available instance of a class. Therefore the constructor is set to private and the class maintains, in this case, a getInstance() method that either calls an existing instance variable, INST in this class, or creates a new one for the executing program. The answer is probably 1, because it's not thread safe. It may be confused for 3, which I had put down earlier, but that is by design, technically, so not actually a flaw.
Here's an example of Lazy Initialization, thread-safe singleton pattern from Wikipedia:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class){
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
Setting the instance variable to volatile tells Java to read it from memory and to not set it in cache.
Synchronized statements or methods help with concurrency.
Read more about double checked locking which is what happens for a "lazy initialization" singleton
More than one instance of Bolton can be created
This option is correct due to lack of synchronization in the above code.
Suppose two threads concurrently check for null and both will find that the value is null and both will call the constructor (which refutes singleton).
Also there is other catch in this, even if two threads dont check for null together but suppose one thread calls the constructor; but the constructor wont return till the object is constructed (assuming that the object is costly to create and requires time), so till the constructor returns some other thread might check for the null condition and still find the object as null as the object is not yet constructed.
This scenario in which some pre condition is called check-then-act which is culprit for Race.
For singleton there are two standards that are being used:
Double Checked locking
Enum based singleton pattern
UPDATE:
Here is another great article which discusses the double checked locking
Interviewer basically wants to check your knoweldge of Singleton pattern . Can the pattern be broken?. Ans is Yes. Check this or google - when singleton is not a singleton.
Best course is to use Enum based Singleton as suggested by Joshua Bloch
The getInstance() method should be synchronized, otherwise many instances could be created if multiple threads calls getInstance() at the same time. So I would select option 1.
We use Singleton Pattern when we want to have only one object of this class and it will be used every where. So to restrict the class to create many objects, we should use private for constructor of this class. And create one public function to return the object of this class.
public class MethodWin {
private int isLoggedOn=0;
private static MethodWin objectMethodWin = new MethodWin();
private MethodWin() { }
public static MethodWin getInstance() {
return objectMethodWin;
}
public void setIsLoggedOn(int value) {
this.isLoggedOn=value;
}
public int getIsLoggedOn() {
return this.isLoggedOn;
}
}
So when we need to create this obect, we should:
MethodWin meth = MethodWin.getInstance();
Original Answer is that only one instance of Bolton is created.
Through reflection we can create many objects even if the constructor is private. In multi-threaded environment there are chances to create more than one instance. Through serialization there are chances to create more than one object.
simple answer is 2) A Bolton will never be created because when you create instance the constructor will call inside constructor initialization when call getInstance method then answer will be single instance will be created.

Volatile keyword: is the variable I am using among two threads synchronized?

I have a code like the one below where an object is shared among two threads (the main thread and the Monitor thread). Do I have to declare MyObject globally and make it volatile to ensure it will be pushed to memory? Otherwise the if statement can print "Not null" if MyObject is only locally accessed by the thread and is not declared volatile, right?
public static void main(String[] args) {
MyObject obj = MyObjectFactory.createObject();
new Monitor(obj).start();
Thread.sleep(500);
if(obj == null)
System.out.println("Null");
else
System.out.println("Not null");
}
public void doSomethingWithObject(MyObject obj) {
obj = null;
}
private class Monitor extends Thread {
public Monitor(MyObject obj) {
this.obj=obj;
}
public void run() {
doSomethingWithObject(obj);
}
}
Note: The code example may not compile since I wrote it myself here on Stackoverflow. Consider it as a mix of pseudo code and real code.
The instance is shared but the references to it are not. Example:
String a = "hello";
String b = a;
b = null; // doesn't affect a
a and b are references to the same instance; changing one reference has no effect on the instance or any other references to the same instance.
So if you want to share state between threads, you will have to create a field inside MyObject which has to be volatile:
class MyObject { public volatile int shared; }
public void doSomethingWithObject(MyObject obj) {
obj.shared = 1; // main() can see this
}
Note that volatile just works for some types (references and all primitives except long). Since this is easy to get wrong, you should have a look at types in java.util.concurrent.atomic.
[EDIT] What I said above isn't correct. Instead, using volatile with long works as expected for Java 5 and better. This is the only way to ensure atomic read/writes for this type. See this question for references: Is there any point in using a volatile long?
Kudos go to Affe for pointing that out. Thanks.
You would rather have to synchronize on the object to ensure it will be set to null before the if check. Setting it to volatile only means changes will be "seen" immediately by other threads, but it is very likely that the if check will be executed before the doSomethingWithObject call.
If you want your object to go through a read-update-write scheme atomically, volatile won't cut it. You have to use synchronisation.
Volatility will ensure that the variable will not be cached in the current thread but it will not protect the variable from simultaneous updates, with the potential for the variable becoming something unexpected.
IBM's developerWorks has a useful article on the subject.
Your example consists only one thread, Monitor, which is created and run in main().
"make it volatile to ensure it will be pushed to memory?" - on the contrary, when you declare a variable as volatile - it ensures that it's NOT being "pushed" (cached) to the thread-local memory, cause there might be other threads that will change the value of the variable.
In order to make sure you print the correct value of a variable you should synchronize the method doSomethingWithObject (change the signature of the method to):
public synchronized void doSomethingWithObject(MyObject obj)
or create synchronized blocks around:
obj = null;
and
this.obj=obj;

Can you safely synchronize on a Java method parameter?

Take this code:
public class MyClass {
private final Object _lock = new Object();
private final MyMutableClass _mutableObject = new MyMutableClass()
public void myMethod() {
synchronized(_lock) { // we are synchronizing on instance variable _lock
// do something with mutableVar
//(i.e. call a "set" method on _mutableObject)
}
}
}
now, imagine delegating the code inside myMethod() to some helper class where you pass the lock
public class HelperClass {
public helperMethod(Object lockVar, MyMutableClass mutableVar) {
synchronized(lockVar) { // we are now synchronizing on a method param,
// each thread has own copy
// do something with mutableVar
// (i.e. call a "set" method on mutableVar)
}
}
}
can "myMethod" be re-written to use the HelperClass by passing its lock var, so that everything is still thread safe? i.e.,
public void myMethod() {
_helperObject.helperMethod(_lock, _mutableObject);
}
I am not sure about this, because Java will pass the lockVar by value, and every thread will get a separate copy of lockVar (even though each copy points to the same object on the heap). I guess the question comes down to how 'synchronized' keyword works -- does it lock on the variable, or the value on the heap that the variable references?
Synchronization is done upon objects, not variables.
Variables/members [sometimes] contain objects and it is the resulting object contained in [variable] x that is actually synchronized upon in synchronized(x).
There are a few other issues with thread-visibility of variables (e.g. might read a "stale" object from a variable), but that does not apply here: there is no re-assignment of _lock and the visibility of the initial ("final") assignment is guaranteed. Because of this it is guaranteed that, in this case, the method parameter will always contain the correct (same) object used for the synchronization.
If the lock object used (where presumably _lock is not final) changes, however, then that would require re-evaluation of the appropriate values/thread-visibility but otherwise does not differ from any cross-thread access.
Happy coding.

Categories