I ran across a class that was set up like this:
public class MyClass {
private static boolean started = false;
private MyClass(){
}
public static void doSomething(){
if(started){
return;
}
started = true;
//code below that is only supposed to run
//run if not started
}
}
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change. Instead you should use parameters. My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once.
So could anyone explain to me why this does not break?
The method doSomething() and the variable started are both static, so there is only one copy of the variable and it is accessible from doSomething(). The first time doSomething() is called, started is false, so it sets started to true and then does... well, something. The second and subsequent times it's called, started is true, so it returns without doing anything.
There's no reason why using a static variable wouldn't work. I'm not saying it's particularly good practice, but it will work.
What should happen is:
The first call is made. The class is initialised, started is false.
doSomething is called. The if fails and the code bypasses it. started is set to true and the other code runs.
doSomething is called again. The if passes and execution stops.
The one thing to note is that there is no synchronization here, so if doSomething() was called on separate threads incredibly close together, each thread could read started as false, bypass the if statement and do the work i.e. there is a race condition.
The code given is not thread safe. The easy way to make this code thread safe would be to do something like
public class MyClass {
private static AtomicBoolean started = new AtomicBoolean(false);
private MyClass(){
}
public static void doSomething(){
boolean oldValue = started.getAndSet(true);
if (oldValue)
return;
}
//code below that is only supposed to run
//run if not started
}
}
This should be thread safe as the AtomicBoolean getAndSet is synchronized.
Admittedly this is not an issue if you do not use threads (please note that a webapp can use quite a lot of threads handling various requests without you being aware of that).
It's not particularly nice code - generally designs should use object instances where state changes, but there's nothing illegal with it.
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change.
You seem to have extrapolated from a design guideline to a language feature. Read one of the many Java tutorials available on line as to what is actually allowed in the language. You can use non-final static fields freely in static methods, but it leads to procedural rather than object-oriented code.
Instead you should use parameters.
It's hard to see how an started parameter would be used - if the caller knew that the process has been started, why would they call the method?
Within static method, you are allowed to invoke or access static members within the same class.
Disregarding multiple threads scenarios,
The first call to doSomething will make the boolean static variable to true, therefore, the second call will execute the code of if block which just simply exit the method.
You static method is talking to a static class variable, so it should be fine. You could think of this as global code and a global variable, tho it IS in the namespace of the class.
If you tried to access a non-static member variable:
private int foo = 0;
from within the static method, the compiler will and should complain.
started is false - initial state.
MyClass.doSomething() - statered is now true
MyClass.doSomething() - started is STILL true
MyClass foo = new MyClass();
foo.started -> it's STILL true, because it's static
foo.doSomething() - not sure you can do this in Java, but if you can, it's be STILL TRUE!
Now, there are issues in the above code with thread safety, but aside from that, it appears to be working as designed.
Just remember the thumb rule that "Static variables are class-level variables and all non-static variables are instance variables". Then you won't have any confusion at all!
i.e.
For static variable, All references made in code to the variable point to same memory location. And for non-static variable, new memory allocation is done whenever new instance of that class is created (so every reference made in code to the variable points to a different memory location allocated for calling class instance).
The code above works completely well (unless it runs in a multithreaded environment). Why do you think it should break?
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change
I guess only static members can be accessed. It need not be constant!
My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once
Per the existing logic. Only the first call runs the //code to be run part
Related
One static method Func() is defined within a class. Invoking it in this.Func does not have compile error. Also, invoking static method against an object doesnt have any disadvantage. And make calling method simple since the class name might be difficult to spell.
Not sure, this is a good java coding way.
If you are calling a static method, you shouldn't use an instance, even though it compiles because it is plain confusing. Consider the following.
Thread t = new Thread( ... );
t.start();
t.sleep(1000);
The last method doesn't operate on the thread t as it is static. It causes the current thread to sleep.
Thread t = null;
t.yield(); // compiles and runs even thought `t` is null.
It is better to use this with class name to maintain the readability because if someone wants to debug in your code, so he has not to go back and see your variable declaration that it is marked as static or not, so it is better to use with class name so no need to go back and think about it
ya it is the possible duplicate of stackoverflow.com/questions/7884004/… –
I would like to known if each instance of a class has its own copy of the methods in that class?
Lets say, I have following class MyClass:
public MyClass {
private String s1;
private String s2;
private String method1(String s1){
...
}
private String method2(String s2){
...
}
}
So if two differents users make an instance of MyClass like:
MyClass instanceOfUser1 = new MyClass();
MyClass instanceOfUser2 = new MyClass();
Does know each user have in his thread a copy of the methods of MyClass? If yes, the instance variables are then thread-safe, as long as only the instance methods manipulate them, right?
I am asking this question because I often read that instance variables are not thread-safe. And I can not see why it should be like that, when each user gets an instance by calling the new operator?
Each object gets its own copy of the class's instance variables - it's static variables that are shared between all instances of a class. The reason that instance variables are not necessarily thread-safe is that they might be simultaneously modified by multiple threads calling unsynchronized instance methods.
class Example {
private int instanceVariable = 0;
public void increment() {
instanceVariable++;
}
}
Now if two different threads call increment at the same then you've got a data race - instanceVariable might increment by 1 or 2 at the end of the two methods returning. You could eliminate this data race by adding the synchronized keyword to increment, or using an AtomicInteger instead of an int, etc, but the point is that just because each object gets its own copy of the class's instance variables does not necessarily mean that the variables are accessed in a thread-safe manner - this depends on the class's methods. (The exception is final immutable variables, which can't be accessed in a thread-unsafe manner, short of something goofy like a serialization hack.)
Issues with multi-threading arise primarily with static variables and instances of a class being accessed at the same time.
You shouldn't worry about methods in the class but more about the fields (meaning scoped at the class level). If multiple references to an instance of a class exist, different execution paths may attempt to access the instance at the same time, causing unintended consequences such as race conditions.
A class is basically a blueprint for making an instance of an object. When the object is instantiated it receives a spot in memory that is accessed by a reference. If more than one thread has a handle to this reference it can cause occurrences where the instance is accessed simultaneously, this will cause fields to be manipulated by both threads.
'Instance Variables are not thread safe' - this statement depends on the context.
It is true, if for example you are talking about Servlets. It is because, Servlets create only one instance and multiple threads access it. So in that case Instance Variables are not thread safe.
In the above simplified case, if you are creating new instance for each thread, then your instance variables are thread safe.
Hope this answers your question
A method is nothing but a set of instructions. Whichever thread calls the method, get a copy of those instructions. After that the execution begins. The method may use local variables which are method and thread-scoped, or it may use shared resources, like static resources, shared objects or other resources, which are visible across threads.
Each instance has its own set of instance variables. How would you detect whether every instance had a distinct "copy" of the methods? Wouldn't the difference be visible only by examining the state of the instance variables?
In fact, no, there is only one copy of the method, meaning the set of instructions executed when the method is invoked. But, when executing, an instance method can refer to the instance on which it's being invoked with the reserved identifier this. The this identifier refers to the current instance. If you don't qualify an instance variable (or method) with something else, this is implied.
For example,
final class Example {
private boolean flag;
public void setFlag(boolean value) {
this.flag = value;
}
public void setAnotherFlag(Example friend) {
friend.flag = this.flag;
}
}
There's only one copy of the bytes that make up the VM instructions for the setFlag() and setAnotherFlag() methods. But when they are invoked, this is set to the instance upon which the invocation occurred. Because this is implied for an unqualified variable, you could delete all the references to this in the example, and it would still function exactly the same.
However, if a variable is qualified, like friend.flag above, the variables of another instance can be referenced. This is how you can get into trouble in a multi-threaded program. But, as long as an object doesn't "escape" from one thread to be visible to others, there's nothing to worry about.
There are many situations in which an instance may be accessible from multiple classes. For example, if your instance is a static variable in another class, then all threads would share that instance, and you can get into big trouble that way. That's just the first way that pops into my mind...
I want to keep track of values of an instance variable, and my breakpoint starts at a static method. I can't check the instance variable value. Is there a way to do that? I searched over google, but found no clue.
Is it because instance can't be accessed in a static method?
You could pass the variable that you are tracking into the method. Although you just make a note every time you do this so you can remove it when you are done testing.
But honestly, if you don't have access to the variable from within the method, then it probably won't change by the time you have exited the method, unless you have multiple threads. Therefore, you can set the breakpoint after/before the method is called.
A static method cannot access the value of an instance variable, which, by definition, is undefined until an instance of the object is created.
public class A {
private int b;
public static void foo() {
b = 1;
}
}
Will not compile for this very reason. A work around it to make b itself static. Of course, you should understand what making b static means. It means that there is exactly one instance of b no matter how many instances of the class exist within a given JVM.
I'm working on a TCP socket right now.
I derive my server class from Thread.
public class TCPServer extends Thread {
public static int SERVERPORT = 54321;
....
<code>
}
When I use this class, it will open several threads. My question is, does each thread have its own static variable SERVERPORT?
Because it seems like if I edit this variable, it does not have effect in others.
My solution to this problem would be to create another class, say "GlobalVariables" and give this class access to it.
My question is, does each thread have its own static variable SERVERPORT?
No, it does not. The variable is shared by all threads in the process.
I missed removing the final :D The variable I have is of type static boolean
Even though the variable is shared, when you modify it in one thread, the change won't necessarily become visible to other threads until some later, unspecified, time.
You need to take steps to ensure visibility. Depending on what your code is doing, this can include:
explicit synchronization;
using a volatile boolean;
using AtomicBoolean.
I've been using scala's lazy val idiom a lot and I would like to achieve something similar in Java. My main problem is that to construct some value I need some other value which is not known at object construction time, but I do not want to be able to change it afterwards. The reason for that is, I'm using a GUI library which instanciates the object on my behalf and calls a different method when everything I need is created, which is when I know the values I need.
Here are the properties I try to achieve:
* Immutability of my variable.
* Initialization in some other method than the constructor.
I do not think this is possible in Java, for only final achieves immutability of the variable and final variables cannot be initialized outside of the constructor.
What would be the closest thing in Java to what I am trying to achieve ?
One way to do it would be to push the actual instantiation of the value in question into another class. This will be final, but won't be actually created until the class is loaded, which is deferred until it is needed. Something like the following:
public class MyClass
{
private static class Loader
{
public static final INSTANCE = new Foo();
}
Foo getInstance()
{
return Loader.INSTANCE;
}
}
This will lazily initialise the Foo as and when desired.
If you absolutely need the Foo to be an instance variable of your top-level class - I can't think of any way off-hand to do this. The variable must be populated in the constructor, as you noted.
In fact I'm not sure exactly how Scala gets around this, but my guess would be that it sets the lazy val variable to some kind of thunk which is replaced by the actual object when first evaluated. Scala can of course do this by subverting the normal access modifiers in this case, but I don't think you can transparently do this in Java. You could declare the field to be e.g. a Future<Foo> which creates the value on first invocation and caches it from that point on, but that's not referentially transparent, and by the definition of final I don't see a way around this.
Andrzej's answer is great, but there is also a way to do it without changing the source code. Use AspectJ to capture Constructor invocations and return non-initialized objects:
pointcut lazyInit() : execution(* com.mycompany.expensiveservices.*.init(*));
void around() : lazyInit() && within(#Slow *) {
new Thread(new Runnable(){
#Override
public void run(){
// initialize Object in separate thread
proceed();
}
}
}
Given this aspect, all constructors of objects marked with a #Slow annotations will be run in a separate thread.
I did not find much reference to link to, but please read AspectJ in Action by Ramnivas Laddad for more info.