Related
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 have a web app that uses some jars written by me.
My challenge is that i have a critical (but fast) section in my code.
1 - I have an object of a given class that has a couple of static fields. Let's call this class A
2 _ A exposes a not static method that access the static fields. for reading and writting. Lets call this method doJob.
3 - Every request instantiates an object of the class A and calls doJob.
A a = new A(); a.doJob();
4 - I assume that every request is creating a new Thread where doJob is executed.
5 - If I define doJob as public synchronized void doJob () {//Do the job} only one Thread at a time will be executing the method and the others will keep waiting.
The question is: Is it all right what i am saying?
You are right, but doJob will be synchronized at instance level, so doJob method could be executed in the same time by two or more different threads on two or more instances of class A. If you want doJob to be executed only by one thread at a time (e.g because it chages static fields) you should either declare it static or synchronize the whole method body using a static field as locking object.
Given that you're trying to guard static (i.e. one per class) fields with non-static (i.e. one per object) monitors, I would say that the "only one thread at a time will be executing the method and the others will keep waiting" claim does not hold.
No.
Marking an instance method as synchronized means the same that doing
public void myMethod() {
synchronized(this) {
...
}
}
So, you can only guarantee that two threads are not running the same method of the same object. The same method from another object can be run simultaneously.
Try to synchronize with a more "static" object. I would use the class object itself, or some static (and inmutable) member.
yes, you're outline is correct. and it does technically bottleneck the system while the other threads wait for access. and this is perfectly fine and normal as long as you avoid putting any heavy processing or i/o within the synchronized block.
I have a web application running on Tomcat.
There are several calculations that need to be done on multiple places in the web application. Can I make those calculations static helper functions? If the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel? Or does one request have to wait until the other request finished the call?
public class Helper {
public static void doSomething(int arg1, int arg2) {
// do something with the args
return val;
}
}
if the calls run parallel:
I have another helper class with static functions, but this class contains a private static member which is used in the static functions. How can I make sure that the functions are thread-safe?
public class Helper {
private static SomeObject obj;
public static void changeMember() {
Helper.obj.changeValue();
}
public static String readMember() {
Helper.obj.readValue();
}
}
changeValue() and readValue() read/change the same member variable of Helper.obj. Do I have to make the whole static functions synchronized, or just the block where Helper.obj is used? If I should use a block, what object should I use to lock it?
can i make those calculations static helper functions? if the server has enough processor cores, can multiple calls to that static function (resulting from multiple requests to different servlets) run parallel?
Yes, and yes.
do i have to make the whole static functions synchronized
That will work.
or just the block where Helper.obj is used
That will also work.
if i should use a block, what object should i use to lock it?
Use a static Object:
public class Helper {
private static SomeObject obj;
private static final Object mutex = new Object();
public static void changeMember() {
synchronized (mutex) {
obj.changeValue();
}
}
public static String readMember() {
synchronized (mutex) {
obj.readValue();
}
}
}
Ideally, though, you'd write the helper class to be immutable (stateless or otherwise) so that you just don't have to worry about thread safety.
You should capture the calculations in a class, and create an instance of the class for each thread. What you have now is not threadsafe, as you are aware, and to make it threadsafe you will have to synchronize on the static resource/the methods that access that static resource, which will cause blocking.
Note that there are patterns to help you with this. You can use the strategy pattern (in its canonical form, the strategy must be chosen at runtime, which might or might not apply here) or a variant. Just create a class for each calculation with an execute method (and an interface that has the method), and pass a context object to execute. The context holds all the state of the calculation. One strategy instance per thread, with its context, and you shouldn't have any issues.
If you don't have to share it you can make it thread local, then it doesn't have to be thread safe.
public class Helper {
private static final ThreadLocal<SomeObject> obj = new ThreadLocal<SomeObject>() {
public SomeObject initialValue() {
return enw SomeObject();
}
}
public static void changeMember() {
Helper.obj.get().changeValue();
}
public static String readMember() {
Helper.obj.get().readValue();
}
}
I'll sum up here what has been said in the comments to the Matt Ball's answer, since it got pretty long at the end and the message gets lost: and the message was
in a shared environment like a web/application server you should try very hard to find a solution without synchronizing. Using static helpers synchronized on static object might work well enough for stand alone application with a single user in front of the screen, in a multiuser/multiapplication scenario doing this would most probably end in a very poor performance - it would effectively mean serializing access to your application, all users would have to wait on the same lock. You might not notice the problem for a long time: if the calculation are fast enough and load is evenly distributed.
But then all of a sudden all your users might try to go through the calculation at 9am and you app will stop to work! I mean not really stop, but they all would block on the lock and make a huge queue.
Now regardless the necessity of a shared state, since you originally named calculations as subject of synchronization: do their results need to be shared? Or are those calculations specific to a user/session? In the latter case a ThreadLocal as per Peter Lawrey would be enough. Otherwise I'd say for overall performance it would be better to duplicate the calculations for everybody needing them in order not to synchronize (depends on the cost).
Session management should also be better left to the container: it has been optimized to handle them efficiently, if necessary including clustering etc. I doubt one could make better solution without investing lot of work and making lots of bugs on the way there. But as Matt Ball has stated it should be better asked separately.
In the first case you don't have to worry about threading issues, because the variables are local to each thread. You correctly identify the problem in the second case, though, because multiple threads will be reading/writing the same object. Synchronizing on the methods will work, as would synchronized blocks.
For the first part:
Yes, these calls are independent and run in parallel when called by different threads.
For the last part:
Use synchronize blocks on the concurrent object, a dummy object or class object. Be aware of cascaded synchronize blocks. They can lead into dead locks when acquired in different order.
If you are worried about synchronization and thread safety, don't use static helpers. Create a normal class with your helper methods and create an instance upon servlet request. Keep it simple :-)
For the sake of not going too deep into what my software is supposed to do let me just give an example of what i am trying to solve, to make this short and sweet.
Lets say i have a Base Class called X and an implementation of that class, i will call Y. Class Y, naturally, extends Base Class X. Lets say I have 20 objects that will be instantiating Class Y via a separate thread for each object and with every instantiation a big file is loaded into memory. Some of these objects, perhaps, might need to use different files but to make this simple, lets say they all need access to the same file.
Is there a way to define a certain object(variable) that points to these files statically in the base class so that, even though the implementation class is loaded 20 times via 20 different threads, they all can share the same static object, so that the file only needs to be loaded one time???
thanks for your help in advance...
is that file read-only?
is it a big string of data?
if so and a String just make it a protected static final String and it is thread safe. if it is mutable you have a whole world of hurt in your future.
if it is a binary and will only be used in a read-only manner you can probably do the same thing with a byte[] in place of the String and make sure you don't let anything change the bytes in the array. A better way would be to implement some Stream or Reader interface in a read-only manner.
the simplest and safest way to make something thread safe is make it immutable. the final keyword makes references immutable, it doesn't make the object it points to immutable. Since a String is immutable the final makes the reference immutable as well and you are good to go. If you need mutability with the changes shared amongst all the threads, the java.util.concurrent package will be your friend.
If you make the variable protected static final then all instances of the subclass regardless of the thread of execution they are on will see the data.
If you know the file ahead of time, you could open and load the file in a static initializer block, and store the contents in a static data member. Then the content will be accessible for all instances of that class, regardless of what thread is currently accessing the instance objects.
// In the base class
protected static final String fileContents;
static {
fileContents = readStuffFromFile();
}
You can start by using ConcurrentHashMap.
Make a key to the map a string and the value should be whatever the loaded representation must be.
Note that if you change the loaded file data you still need to ensure thread safety even if you are using ConcurrentHashMap.
Initialize this map before creating your objects and pass it to the object's constructor.
Create a separate object to store the cached contents of the file.
Make this object thread-safe as necessary through synchronization so that multiple threads can access this object. In your base class X, put a reference to this object. Now, multiple instances of class X could be instantiated with the same cached object. This now requires that this object only be loaded once per file and the object can be shared across as many X/Y objects as necessary.
The only problem that remains is having a method of loading these files. The solution to this will depend upon the structure of your application and these files, but I will offer one possible solution.
Create a factory class which will create objects of this new type. This factory will run on its own thread, and all files loaded will be loaded through this factory. Create an interface where a file can be requested from this factory. The factory keeps a reference to all files that are loaded, so if it's already loaded it can just immediately give the reference back. When it's not loaded, block the thread making the call using Object.wait() on a placeholder object stored in the factory related to this file. Once the factory is done loading the file, call Object.notifyAll() on the placeholder object for that file which will wakeup each thread and those methods will return with the reference to the loaded file.
Once this is complete, each thread which needs a file can just call the method on the factory to get the file object. This thread will now block until the file object is loaded and then the function will return. As long as this is okay, which it seems it should be since those threads will be waiting for the file to load anyways, then this solution should work well.
a non-static inner class will fulfill all your desires:
public class Foo {
protected String member;
public Foo(String member) {
this.member = member;
}
public class Bar {
protected String member;
public Bar(String member) {
this.member = member;
}
public void show() {
System.out.println("this.member: " + this.member + "; Foo.this.member: " + Foo.this.member);
}
}
public static void main(String[] args) throws javax.mail.MessagingException, java.io.IOException {
Foo foo_a = new Foo("a");
Foo foo_b = new Foo("b");
Bar bar_a1 = foo_a.new Bar("1");
Bar bar_a2 = foo_a.new Bar("2");
Bar bar_b1 = foo_b.new Bar("1");
Bar bar_b2 = foo_b.new Bar("2");
bar_a1.show();
bar_a2.show();
bar_b1.show();
bar_b2.show();
}
}
Well, well, well, (-2 votes later):
Firstly, none of the above solutions address the part of the original question that there may not be exactly 1 file shared by all objects. One group of objects may need to share file A, and another group file B, and so forth. The inner class solution above is intended to fulfill exactly that requirement. You instantiate the outer class once per file/group, and you instantiate inner objects for a group from the same outer object.
Secondly, static is a poor choice: it is quite likely that the file might need to be specified later during the run-time rather than at program startup. The outer/inner class structure above addresses exactly that issue. You instantiate the outer class whenever you need to. No static initialization is needed (nor any complicated schemes for deferred static initialization).
Thirdly, thread paranoia was simply not an issue in this problem (or this solution). It is pretty clear that the file is a read-only, hence immutable, so going all concurrent on the problem will only detract from elegant solutions.
Finally, speaking of elegant, this one is, and probably the only one.
This update is mostly for someone new who comes and looks at the thread, since the negative voters in this thread will probably get this to -5.
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