I had a recent interaction with one experienced java person and he asked me a simple question "When do u think we should use Abstract classes and when we should use interfaces".
The question seemed to be trivial and i came up with standard answers like interfaces support multiple inheritance and it makes our code debugging easier, abstract class can declare a non abstract method also. So it depends on the requirement.
But these are all java theory concepts and the question is more about java designing.
Yes its true that it depends upon requirement but the point is how to analyse the requirement for the use for interface or abstract class.
Lets take an example go into more details.
A company manufactures various kinds of clocks and it wants to develop a software so that it get details clock.
1st approach using Interface : An interface by the name clock is created which defines a method "getTime()". Now they have different types of clock like mechanical , electronic etc, so they extend this interface and create MechanicalClock , ElectronicClock interfaces etc. Code was tested and debugging was done and everything was working fine and suddenly a requirement come up that customer also requires an API to get seconds also.
In order to add requirement if you change your interface then everything break and all the classes will have to modified again. This can be very expensive as whole of testing of a stable code will have to done again.
2 approach using Abstract class : If we implement the above scenario using abstract class, our job will be extremely simple. We just have add another non abstract method "getSeconds" in our abstract class and all classes can call it. So job done without any headache.
Its clear that in above scenario we should use AbstractClass.
Let us modify the above scenario. Now company makes a clock which is combination both mechanical and electronic clock.
Now if we have used AbstractClass implementation we are struck and only way out is lots of special case changes or re implemnting the whole hierarchy as java doesn't support multiple inheritance.
Implementation using interface will score out here as we can create a new interface extending MechanicalInterface and ElectronicInterface reason being interface support multiple inheritance.
So to summarise if we want an implementation hierarchy where classes may posess some common behaviour implementation then AbstractClass is the way to go. But if we are not going to maintain an implmentation hierarchy and we might need to combine some unrelated classes in our implementation then interfaces will be better choice.
This decision is very important as a good design forms the base of a good software.
Thursday, April 15, 2010
Wednesday, December 31, 2008
Sharing variable between threads
I take no credit for what I am going to write here, It's the result of reading few good books on Java Concurrency.
Lots of programmers think that synchronization is to be used when multiple threads are modifying a shared variable. What about a situation when we know that only one particular thread will modify the shared variable and all others will only read that variable. Should we be using synchronization?
Consider following example and think about the output:
public class Test {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run(){
while(!ready){
Thread.yield();
}
System.out.println(number);
}
}
public static void main(String[] args)throws Exception {
new ReaderThread().start();
number=42;
ready = true;
}
}
I had my answer 42, its got to be 42. But its not always true. Its quite possible that thread does not see the value of ready and get stuck in infinite loop.
When you run java process with '-server' option, according to JVM specs, JVM can do some optimization. This optimization involves, keeping the value of the local thread specific variables in local registers or caches and update the memory location at will. So unless JVM knows that a particular variable is shared between threads, it can apply some optimizations. If you run the process with '-client' option, JVM does not apply any optimizations and hence you will always see the result as you would expect. Even in production environment, things like above are hard to catch and sometime it can run correctly for its entire life.
In above example, there is no hint to JVM to know that 'ready' is shared, so it can opt to keep the changes in variable in local cache and hence other threads can see the stale value.
So whenever there is any sharing use either final or volatile or synchronization.
Volatile forces JVM to update the shared memory location with each update on the variable and hence all the threads will see the updates value. Similarly with use of synchronization, JVM knows that it has to update the memory location for each update in shared variable.
Lots of programmers think that synchronization is to be used when multiple threads are modifying a shared variable. What about a situation when we know that only one particular thread will modify the shared variable and all others will only read that variable. Should we be using synchronization?
Consider following example and think about the output:
public class Test {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run(){
while(!ready){
Thread.yield();
}
System.out.println(number);
}
}
public static void main(String[] args)throws Exception {
new ReaderThread().start();
number=42;
ready = true;
}
}
I had my answer 42, its got to be 42. But its not always true. Its quite possible that thread does not see the value of ready and get stuck in infinite loop.
When you run java process with '-server' option, according to JVM specs, JVM can do some optimization. This optimization involves, keeping the value of the local thread specific variables in local registers or caches and update the memory location at will. So unless JVM knows that a particular variable is shared between threads, it can apply some optimizations. If you run the process with '-client' option, JVM does not apply any optimizations and hence you will always see the result as you would expect. Even in production environment, things like above are hard to catch and sometime it can run correctly for its entire life.
In above example, there is no hint to JVM to know that 'ready' is shared, so it can opt to keep the changes in variable in local cache and hence other threads can see the stale value.
So whenever there is any sharing use either final or volatile or synchronization.
Volatile forces JVM to update the shared memory location with each update on the variable and hence all the threads will see the updates value. Similarly with use of synchronization, JVM knows that it has to update the memory location for each update in shared variable.
Sunday, August 24, 2008
few things to remember while using logging frameworks
Use of debug/info etc methods from any logging framework (like log4j) helps you to get important information from your application and helps you analyze problems in the application.
It's helpful to use logging messages as much as possible keeping in mind the information you might need while analyzing some problems. But also there are a few things, one should keep in mind while using them.
Take an example,
List aList = new ArrayList();
//do some operations on list
//print the list contents
log.debug(aList.toString());
You might think that you have used debug method so this rather not so important information will not get printed when log level is more than debug. But, do consider the size of the list. No matter what the debug level is, the toString method will always get executed. In your production environment, though the content of the list will not get printed, but the toString method will always get executed, and depending upon the size of the list, it might take considerable amount of cpu time.
I such cases, one can check the log level and then call the methods, hence triggers only an integer comparison.
if(log.level <= debug)
log.debug(aList.toString());
It's helpful to use logging messages as much as possible keeping in mind the information you might need while analyzing some problems. But also there are a few things, one should keep in mind while using them.
Take an example,
List aList = new ArrayList();
//do some operations on list
//print the list contents
log.debug(aList.toString());
You might think that you have used debug method so this rather not so important information will not get printed when log level is more than debug. But, do consider the size of the list. No matter what the debug level is, the toString method will always get executed. In your production environment, though the content of the list will not get printed, but the toString method will always get executed, and depending upon the size of the list, it might take considerable amount of cpu time.
I such cases, one can check the log level and then call the methods, hence triggers only an integer comparison.
if(log.level <= debug)
log.debug(aList.toString());
Friday, July 25, 2008
concurrency in java - I
Concurrency in Java is easy, but it's tricky. If you don't use it wisely, you will end up in a mess. The other important thing is to know about the features which Java provides out of the box.
Hash map is handy, we all use it. To use it in multi threaded applications Java provides synchronized hash map, which is a wrapper for hash map.
Synchronized hash map uses the lock on the whole map, which can impact performance when multiple threads access the map too often and spend time to acquire the lock. Data structure for map is a table with hashing and chaining. So, when one thread is trying to put a value in map, it would access one row (the whole chain in that row) in table. Locking only that particular row will help, but synchronized map will lock the whole map, hence block all other threads.
Java also provides concurrent hash map, which uses strip locking, which is , lock the row of the table and not the whole table. Hence multiple threads can access the map without any concurrency problem.
Hash map is handy, we all use it. To use it in multi threaded applications Java provides synchronized hash map, which is a wrapper for hash map.
Synchronized hash map uses the lock on the whole map, which can impact performance when multiple threads access the map too often and spend time to acquire the lock. Data structure for map is a table with hashing and chaining. So, when one thread is trying to put a value in map, it would access one row (the whole chain in that row) in table. Locking only that particular row will help, but synchronized map will lock the whole map, hence block all other threads.
Java also provides concurrent hash map, which uses strip locking, which is , lock the row of the table and not the whole table. Hence multiple threads can access the map without any concurrency problem.
JMX - way to go
I knew next to nothing about JMX until recently, and then I had the opportunity to explore it. JMX can be used in building distributed application, building monitoring tools for applications.
With JMX lots of things get easier. I really do not intend to repeat the information which is available on internet and let me tell you, you will get plenty of good web-sites if you search on google. Instead I want to touch a few points which give good impression to a newbie who knows a little about JMX.
First of all, use of JMX is really easy. Starting with 1.5, JDK comes with JMX console Jconsole, which can be used to explore the mbeans (management beans, the beans which you register with mbean server).
To simplify matters further, there is Spring. Spring really makes it a lot easier to use JMX. A couple of configuration in xml and you are ready to see the JMX in action.
With JMX, you can see runtime information about your applications. You can expose the information through mbeans and can access them while your application is running, hence helps in monitoring.
Remember log4j, how it makes life so much easier. And remember when you face an issue in production environment and all you can do is, analyzing logs; but wait a minute, you realize that log levels are set to INFO or ERROR but you want to make them DEBUG. With log4j and JMX you can do this with a click of mouse.
You can go further to hook the JMX with snmp and let your existing snmp tool monitor your application with subagent talking to Mbean server.
Tomcat and many application servers also expose mbeans which you can use to know the insight of server.
I hope you felt a little excited about JMX. I do not intend to teach you JMX in this post, but if you wish, we can definitely discuss on this topic further.
With JMX lots of things get easier. I really do not intend to repeat the information which is available on internet and let me tell you, you will get plenty of good web-sites if you search on google. Instead I want to touch a few points which give good impression to a newbie who knows a little about JMX.
First of all, use of JMX is really easy. Starting with 1.5, JDK comes with JMX console Jconsole, which can be used to explore the mbeans (management beans, the beans which you register with mbean server).
To simplify matters further, there is Spring. Spring really makes it a lot easier to use JMX. A couple of configuration in xml and you are ready to see the JMX in action.
With JMX, you can see runtime information about your applications. You can expose the information through mbeans and can access them while your application is running, hence helps in monitoring.
Remember log4j, how it makes life so much easier. And remember when you face an issue in production environment and all you can do is, analyzing logs; but wait a minute, you realize that log levels are set to INFO or ERROR but you want to make them DEBUG. With log4j and JMX you can do this with a click of mouse.
You can go further to hook the JMX with snmp and let your existing snmp tool monitor your application with subagent talking to Mbean server.
Tomcat and many application servers also expose mbeans which you can use to know the insight of server.
I hope you felt a little excited about JMX. I do not intend to teach you JMX in this post, but if you wish, we can definitely discuss on this topic further.
Thursday, July 24, 2008
More Questions !!
What are the different type of references in Java ?
What is a ClassLoader, when will you need one, what are the different types of class loaders in Java ?
What are the various aspects of Java that are NOT Platform dependent ?
What is the difference between extending the Thread Class and implementing Runnable.. No the answer is not that you can extend only one class :-)
If you have a Static Method in Java that is Synchronized, how is it different from a Synchronized method of an Object ?
What is the Time Lag between starting a Thread and the actual running of the new Thread ?
What is a ClassLoader, when will you need one, what are the different types of class loaders in Java ?
What are the various aspects of Java that are NOT Platform dependent ?
What is the difference between extending the Thread Class and implementing Runnable.. No the answer is not that you can extend only one class :-)
If you have a Static Method in Java that is Synchronized, how is it different from a Synchronized method of an Object ?
What is the Time Lag between starting a Thread and the actual running of the new Thread ?
Sunday, July 20, 2008
Encapsulation VS Abstraction VS Data Hiding
Most of the books don't really clearly differentiate between Encapsulation, abstraction and Data Hiding and most of the time people treat these terms as synonyms.
When we ask people whts encapsulation ... the answer given is "Code is written in such a manner so that it acts as a capsule. And just like a capsule where we dont know whts inside it similarly we have code and we use it without knowing worrying about whts inside."
Now if we carefully analyse then above definition is mixture of all three terms and its not just encapsulation as is being told.
Data Hiding clearly means we need to hide data but then its our choice wht we need to hide and expose and thats where abstraction comes into picture.
Abstraction refers to deciding what are necessary details which we need to include in our code and expose[just like creating an ADT where mandatory operations are exposed but implementation is hidden]. But the implementation of those details needs to be hidden.
Now encapsulation provides us a placeholder [i.e a set of variables and operations] which is ultimately needed to implement Data Hiding and Abstraction.
When we ask people whts encapsulation ... the answer given is "Code is written in such a manner so that it acts as a capsule. And just like a capsule where we dont know whts inside it similarly we have code and we use it without knowing worrying about whts inside."
Now if we carefully analyse then above definition is mixture of all three terms and its not just encapsulation as is being told.
Data Hiding clearly means we need to hide data but then its our choice wht we need to hide and expose and thats where abstraction comes into picture.
Abstraction refers to deciding what are necessary details which we need to include in our code and expose[just like creating an ADT where mandatory operations are exposed but implementation is hidden]. But the implementation of those details needs to be hidden.
Now encapsulation provides us a placeholder [i.e a set of variables and operations] which is ultimately needed to implement Data Hiding and Abstraction.
Subscribe to:
Posts (Atom)