How to improve Java performace using static variables and threads? - java

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.

Related

Object and instance are same things?

While reading about synchronization, I read static synchronized method locked on class object and synchronized method locks on current instance of an object.
I have confusion what is class object and instance of an object? Don't object and instance are same things?
For every class loaded into JVM , an instance of class Class will be created.
for ex:
Student student = new Student()
when above line of code executed class (Student) get loaded into JVM first bcz JVM needs template to create object .And based on template JVM creates instance of Student in heap .Along with Student instance JVM creates instance of class Class in heap.This class instance all the information about STudent like number of constructors,methods,variables etc we use for reflection.
Now all the instances (object) created will have a lock associated with then which comes into picture when executing synchronized methods or blocks (which can be static or instance) . if you are executing any static methods in synchronized context then lock of Class class (of STudent) will be acquired until its completion .
The operative word there is class. Every class has an instance of java.lang.Class that represents it in the current classloader.
Consider this simple example:
public class MyClass {
public synchronized void instanceMethod() {
// This method will synchronize on the instance of MyClass that called it
}
public static synchronized void staticMethod() {
// This method will synchronize on MyClass.class
}
}
I think whatever you are reading this from could have worded this in a better way.
The difference between synchronised instance methods and synchronised static methods is that the latter "locks" the class while the former locks the instance of that class on which the synchronised method is called. See this answer for more info.
Assuming the author knows what he/she is talking about, the word "class object" creates confusion, because classes themselves are not objects. Is he/she talking about instances of Class<T>? Probably not. The author should have just said "class".
As to what's the difference between "object" and "instance" outside of the context of synchronisation, they mean really the same thing - those things that you create by calling constructors (and string literals).
Personally, I think that the word "object" has a higher level abstraction. When I am talking at a low level of abstraction (talking about individual lines of code e.g. "I created an instance of Foo here by writing new Foo()"), I would use "instance". When I am talking about things on a higher level (like how the whole system works), I tend to use "object". But this might be just me. Other people might use them interchangeably.

Instance methods and thread-safety of instance variables

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...

non-static variable .. cannot be referenced from a static context [duplicate]

This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 8 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
The very common beginner mistake is when you try to use a class property "statically" without making an instance of that class. It leaves you with the mentioned error message:
You can either make the non static method static or make an instance of that class to use its properties.
What the reason behind this? Am not concern with the solution, rather the reason.
private java.util.List<String> someMethod(){
/* Some Code */
return someList;
}
public static void main(String[] strArgs){
// The following statement causes the error.
java.util.List<String> someList = someMethod();
}
You can't call something that doesn't exist. Since you haven't created an object, the non-static method doesn't exist yet. A static method (by definition) always exists.
The method you are trying to call is an instance-level method; you do not have an instance.
static methods belong to the class, non-static methods belong to instances of the class.
The essence of object oriented programming is encapsulating logic together with the data it operates on.
Instance methods are the logic, instance fields are the data. Together, they form an object.
public class Foo
{
private String foo;
public Foo(String foo){ this.foo = foo; }
public getFoo(){ return this.foo; }
public static void main(String[] args){
System.out.println( getFoo() );
}
}
What could possibly be the result of running the above program?
Without an object, there is no instance data, and while the instance methods exist as part of the class definition, they need an object instance to provide data for them.
In theory, an instance method that does not access any instance data could work in a static context, but then there isn't really any reason for it to be an instance method. It's a language design decision to allow it anyway rather than making up an extra rule to forbid it.
I just realized, I think people shouldn't be exposed to the concept of "static" very early.
Static methods should probably be the exception rather than the norm. Especially early on anyways if you want to learn OOP. (Why start with an exception to the rule?) That's very counter-pedagogical of Java, that the "first" thing you should learn is the public static void main thing. (Few real Java applications have their own main methods anyways.)
I think it is worth pointing out that by the rules of the Java language the Java compiler inserts the equivalent of "this." when it notices that you're accessing instance methods or instance fields without an explicit instance. Of course, the compiler knows that it can only do this from within an instance method, which has a "this" variable, as static methods don't.
Which means that when you're in an instance method the following are equivalent:
instanceMethod();
this.instanceMethod();
and these are also equivalent:
... = instanceField;
... = this.instanceField;
The compiler is effectively inserting the "this." when you don't supply a specific instance.
This (pun intended) bit of "magic help" by the compiler can confuse novices: it means that instance calls and static calls sometimes appear to have the same syntax while in reality are calls of different types and underlying mechanisms.
The instance method call is sometimes referred to as a method invocation or dispatch because of the behaviors of virtual methods supporting polymorphism; dispatching behavior happens regardless of whether you wrote an explicit object instance to use or the compiler inserted a "this.".
The static method call mechanism is simpler, like a function call in a non-OOP language.
Personally, I think the error message is misleading, it could read "non-static method cannot be referenced from a static context without specifying an explicit object instance".
What the compiler is complaining about is that it cannot simply insert the standard "this." as it does within instance methods, because this code is within a static method; however, maybe the author merely forgot to supply the instance of interest for this invocation — say, an instance possibly supplied to the static method as parameter, or created within this static method.
In short, you most certainly can call instance methods from within a static method, you just need to have and specify an explicit instance object for the invocation.
The answers so far describe why, but here is a something else you might want to consider:
You can can call a method from an instantiable class by appending a method call to its constructor,
Object instance = new Constuctor().methodCall();
or
primitive name = new Constuctor().methodCall();
This is useful it you only wish to use a method of an instantiable class once within a single scope. If you are calling multiple methods from an instantiable class within a single scope, definitely create a referable instance.
If we try to access an instance method from a static context , the compiler has no way to guess which instance method ( variable for which object ), you are referring to. Though, you can always access it using an object reference.
A static method relates an action to a type of object, whereas the non static method relates an action to an instance of that type of object. Typically it is a method that does something with relation to the instance.
Ex:
class Car might have a wash method, which would indicate washing a particular car, whereas a static method would apply to the type car.
if a method is not static, that "tells" the compiler that the method requires access to instance-level data in the class, (like a non-static field). This data would not be available unless an instance of the class has been created. So the compiler throws an error if you try to call the method from a static method.. If in fact the method does NOT reference any non-static member of the class, make the method static.
In Resharper, for example, just creating a non-static method that does NOT reference any static member of the class generates a warning message "This method can be made static"
The compiler actually adds an argument to non-static methods. It adds a this pointer/reference. This is also the reason why a static method can not use this, because there is no object.
So you are asking for a very core reason?
Well, since you are developing in Java, the compiler generates an object code that the Java Virtual Machine can interpret. The JVM anyway is a binary program that run in machine language (probably the JVM’s version specific for your operating system and hardware was previously compiled by another programming language like C in order to get a machine code that can run in your processor). At the end, any code is translated to machine code. So, create an object (an instance of a class) is equivalent to reserve a memory space (memory registers that will be processor registers when the CPU scheduler of the operating system put your program at the top of the queue in order to execute it) to have a data storage place that can be able to read and write data. If you don’t have an instance of a class (which happens on a static context), then you don’t have that memory space to read or write the data. In fact, like other people had said, the data don’t exist (because from the begin you never had written neither had reserved the memory space to store it).
Sorry for my english! I'm latin!
The simple reason behind this is that Static data members of parent class
can be accessed (only if they are not overridden) but for instance(non-static)
data members or methods we need their reference and so they can only be
called through an object.
A non-static method is dependent on the object. It is recognized by the program once the object is created.
Static methods can be called even before the creation of an object. Static methods are great for doing comparisons or operations that aren't dependent on the actual objects you plan to work with.

Java Static vs Instance

So my coder friend hates using the static coding. Yet my Java program is full of it to link between classes, and I have a lot of them!
Is it worth rewriting the whole code to remove the static method?
Is there any advantage of using one over the other?
1. An instance variable is one per Object, every object has its own copy of instance variable.
Eg:
public class Test{
int x = 5;
}
Test t1 = new Test();
Test t2 = new Test();
Both t1 and t2 will have its own copy of x.
2. A static variable is one per Class, every object of that class shares the same Static variable.
Eg:
public class Test{
public static int x = 5;
}
Test t1 = new Test();
Test t2 = new Test();
Both t1 and t2 will have the exactly one x to share between them.
3. A static variable is initialized when the JVM loads the class.
4. A static method cannot access Non-static variable or method.
5. Static methods along with Static variables can mimic a Singleton Pattern, but IT'S NOT THE RIGHT WAY, as in when there are lots of classes, then we can't be sure about the class loading order of JVM, and this may create a problem.
static is for the cases where you don't want to have copy for each instance
instance variables are for the cases where you want separate copy for each instance of object.
Based on business cases, which one to use may change.
If you have too many static functions and variables it can lead to a more functional approach rather than true OO. Also if you have public static variable then you replicate global variable which are not good. Keeping track of them is a nightmare.
Generally my rule is to use instance variables if you can and only have static variables and functions if it really is generic over a class rather than an object
This is quite a good answer to a similar questions
Java: when to use static methods
Rather than just linking to methods consider using the new operation to create a new object and access the method from that in a non static way.
before
public void myMethod(){
Time.setTime(Time.getTime() + 20);
System.out.println(Time.getTime());
}
after
public void myMethod(){
Time t = new Time();
t.setTime(t.getTime() + 20);
System.out.println(t.getTime());
}
Any state that is held in these methods will now be the to instance of time you have created. You could also share the variable t accross other methods if you needed to.
Garbage Collection - static fields live much longer then instance fields.
From a logic point of view, static fields are ONLy suppose to be shared among every single instance - if it is truly your case then no problem of course.
Are you talking about static methods or static properties?
As far as static methods are concerned, there is only one way to abuse them, and that is when you define methods that take an object instance as a parameter. You should never need to do that and in my view doing so is poor coding practice. Here is an example:
static int add(ThisClass a, ThisClass b) {
return a.value + b.value;
}
If you are talking about static variables in the class, you are basically into the subject of "singletons" which is where there is intended to be only one instance of a particular class. Singletons are subject to a lot of abuse. They are used by many class libraries (think JDNI and the logging classes) but if an application makes extensive use of them it can be a sign of a poorly structured program. That is probably what your friend is bitching about.
Instance and Static variable:
Answer to your Question: I would say it is worth to use static variable to save memory allocation.
Memory allocation:
For static variable only one memory location is allocated irespective to no of object created and for Instance variable each object one memory location allocated
Now consider this example, consider you are working on companies internal project where you have to create 1M object to Employee class and some property to the Employee class are eid, ename, ecompany now Important thing is that all employees are working in XYZ company so value to the property ecompany is gonna be "XYZ" irrespective of Employee.
Now you know the situation, value to the property ecompany is gonna be XYZ for 1 Million Object.
Now you decide you want to declare ecomapny property as static or instance considering memory allocation
if you declare it as a static then minimum memory allocated to ecompany will be only 48 bytes which very less compare to memory needed to store 1 Million instance variable. 100000 * 48 bytes = 48 Million bytes.
When you use static objects (except for the case of singleton) you're actually implementing functional programming combined with global variables. If you do that a lot - you should reconsider either your design or using Java (maybe you should use a functional programing language such as list, scheme etc).
Pro Static
Once a static member is called from the inside or the outside of the class, then the static constructor of the class is called. The "static object" will live through the whole session, hence you will win in performance.
Con Static
Static members cannot have states, hence they cannot talk to non-static members of the class.
Example
If we consider the BigInteger class, this class would gain if some of the parts were made into static members.
An instance of the class represent (as expected) a big integer.
However, the main methods add and multiply are not static (which they should be in a better world), which is bad for performance.
Hence, in practice one should not be afraid of mixes between static and non-static.
I don't like using static variables or methods because they have no real inheritance. This makes it more difficult to mock for testing. Using instances gives you the flexibility of full polymorphism. On the other hand, sometimes static variables are necessary, for example with a global cache. Static methods can be a benefit if they provide helper methods for classes/objects/primitives which you cannot access or extend. These helper methods are so simple they don't need inheritance. For example java.util.Arrays class or java.util.Collections.

Deferred initialization of immutable variables

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.

Categories

Resources