Monday, 8 July 2013

Multi Threading in JAVA

Before going to know about multi threading, we need to know about multi tasking.

What is Multitasking?

Executing several tasks simultaneously is called multitasking.

We have following types of multi tasking.

1. Process-based multitasking
2. Thread-based multitasking 

Executing several task simultaneously where each task is a separate independent process such type of multitasking is called "process based multitasking". 


Example:-While typing a program in the editor we can listen MP3 audio songs. At the same time we download a file from the Internet.   


All these task are executing simultaneously and each task is a separate independent program. hence it is process based multitasking. It is best suitable at operating system level.


Executing several task simultaneously where each task is a separate independent part of the same program is called "thread-based multitasking". and every independent part is called a thread. This type of multitasking is best suitable at programmatic level.


Example:-While typing a some notes in word document it can check for grammer and spelling.


I hope now we got some information about threads. So now we need to know What is multithreading?


Executing several thread simultaneously where each thread is a separate independent part of the same program is called multithreading. Java language provides inbuilt support for multithreading by defining a rich library, classes like Thread, ThreadGroup and interfaces like Runnable etc. Other OOPs languages like c++ does not have built in support for multithreading.



The main advantage of multithreading is reduces response time and improves performance of the system.

We can define the thread in following ways:
  1. By extending Thread class or
  2. By implementing Runnable interface.
Among the two ways of defining a thread implementing Runnable mechanism is always recommended because in first approach as our Thread class already extending Thread there is no chance of extending any other. Hence, we missing the key benefit of oops(inheritance properties).

2. Serialization in JAVA

Example on Serialization:

package com.sample.java.testing;

import java.io.Serializable;

public class SerializationSample implements Serializable{

/**

*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String sex;

public SerializationSample(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}
}


**************************************************

package com.sample.java.testing;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializationExample {
public static void main(String a[]) throws IOException{

SerializationSample example = new SerializationSample("krishna", 24, "male");
FileOutputStream fileOutputStream = new FileOutputStream("D:/serialization.txt");

ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

objectOutputStream.writeObject(example);
}
}

Example on DESerialization:

package com.sample.java.testing;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeSerializationExample{

/**
* @param args
* @throws IOException 
* @throws ClassNotFoundException 
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {

FileInputStream fileInputStream = new FileInputStream("D:/serialization.txt");

ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);

SerializationSample sample = (SerializationSample)inputStream.readObject();

System.out.println(sample.getName());
System.out.println(sample.getAge());

FileOutputStream fileOutputStream = new FileOutputStream("D:/deserialization.txt");

fileOutputStream.write(sample.getName().getBytes());
}

}

Tuesday, 2 July 2013

Serialization in JAVA

Primary purpose of java serialization is to write an object into a stream, so that it can be transported through a network and that object can be rebuilt again.

Object Serialization in Java is a process used to convert "Object" into a binary format which can be persisted into disk or sent over network to any other running Java virtual machine and the reverse process of creating object from binary stream is called deserialization in Java.

Most impressive thing is that this process is JVM independent, meaning an object can be serialized on one platform and deserialized on an entirely different platform.

Java provides Serialization API for serializing and deserializing object which includes java.io.Serializablejava.io.ExternalizableObjectInputStream and ObjectOutputStream etc. 

Classes ObjectInputStream and ObjectOutputStream are high-level streams that contain the methods for serializing and deserializing an object.

Basic guidelines that should be followed for Object serialization:
  1. Any class that wants its objects to be serialized must implement the Serializable interface. The Serializable interface does not have any methods. It merely serves to flag an object as serializable to an ObjectOutputStream.
  2. If there any members in a Serializable class, then the following guidelines apply:
  • If they are primitives, they are automatically serializable.
  • If they are non-primitive objects, they must implement Serializable. If we try to serialize  an object that contains reference to an object that does not implement Serializable then while serializing the object, we get a Runtime Exception.
  • If we have a reference to a non-serializable object in our class, then we have to mark the reference with the keyword transient. The transient keyword on a reference means that when the parent object is serialized then the object whose reference is marked as transient will not be serialized.

How serialization is performed in java:

1. Java provides Serialization API, a standard mechanism to handle object serialization. To persist an object in java, the first step is to flatten the object. For that the respective class should implement "java.io.Serializable" interface. We don't need to implement any methods as this interface do not have any methods. This is a marker interface/tag interface. Marking a class as Serializable indicates the underlying API that this object can be flattened.

2. Next step is to actually persist the object. To persist an object you need to 
  • use node stream to write to file systems or transfer a flattened object across a network wire and have it be rebuilt on the other side. 
  • You can use java.io.ObjectOutputStream class, a filter stream which is a wrapper around a lower-level byte stream. 
  • So to write an object you use "writeObject(<<instance>>)" method of "java.io.ObjectOutputStream" class and to read an object you use "readObject()" method of "java.io.ObjectOutputStream" class. 
  • "readObject()" can read only serialized object, that means if the class does not implement "java.io.Serializable" interface, "readObject()" cannot read that object.
See the following Example:
=========================================
// a non-serializable class
public class NonSer
{
    private Integer modelID;
    private String modelName;
    //rest of the implementations
}

// a serializable class

public class Ser implements Serializable
{
    private int engineID;
    private String engineName;
    // other implementations
}

public class Car implements Serializable

{
    //a primitive, hence serializable
    private int carID; 

    //a non-serializable object, hence transient

    private transient NonSer nonSerRef

    //a serializable object, hence no transient

    private Ser serRef; 
    // other implementations

}

=========================================
Now when we try to serialize an instance of a Car object, there will be no exceptions thrown because all the members of the car object are either primitives, or implement Serializable or are marked with the keyword transient.

Note that in our Car declaration if we had not marked our NonSer object as transient, we would have got a RuntimeException while trying to serialize the Car object.

The above example was a very basic one to show how to serialize an object in Java. Now let us look under the hood as to how Java resolves objects during serialization. To state the problem, consider the following class declarations:

public class Ser implements Serializable
{
    private int ID;
    private String gearName;
    //other members if any
}

public class Car implements Serializable
{
    private int ID;
    private Ser serRef;
    public Car(int i, Ser sRef)
    {
        this.ID = i;
        this. serRef = sRef;
    }
}

Now let us serialize two Car objects:

Ser sRef = new Ser();

Car c1 = new Car(1, sRef);

Car c2 = new Car(2, sRef);

ObjectOutputStream out = new ObjectOutputStream(

        FileOutputStream(“out.dat”));

out.writeObject(c1);

out.writeObject(c2);

out.close();


In the above code snippet, we serialized two Car objects [note the usage of the same Ser object to construct two different Car objects]. The interesting question is: how many Ser objects were serialized? 

There was only one Ser object that both the Car objects were sharing. Hence it should only serialize one Ser object. The answer indeed is one. This can be proved by checking if the serialized Ser object is the same for both the Car objects. Let us look into that:

ObjectInputStream in = new ObjectInputStream(

        new FileInputStream(“out.dat”));

Car first = (Car) in.readObject();

Car second = (Car) in.readObject();

System.out.println(first. getSerType() == second. getSerType());



The above code does print true. Note that here we are testing for object identity of the Ser object instead of logical equality [which is done via equals() method]. The identity test is required because we want to verify whether both the Ser objects are actually the same.

While performing serialization of objects, Java forms a data structure similar to an Object Graph to determine which objects need to be serialized. It starts from the main object to serialize, and recursively traverses all the objects reachable from the main object. For each object that it encounters, which needs serialization, it associates an identifier that marks the object as already been serialized to the given ObjectOutputStream instance. So when Java encounters the same object that has already been marked as serialized to the ObjectOutputStream, it does nor serialize the object again, rather a handle to the same object is serialized. This is how Java avoids having to re-serialize an already serialized object. The seemingly complex problem was solved by the simple method of assigning IDs to objects.

One important thing to note is that if we used different ObjectOutputStream instances to serialize the two Car objects, then Java would have serialized the same Ser object twice albeit in the different streams. This is because the first time Java marks the Ser object with an ID, that ID will associate the object to the first ObjectOutputStream and the next time when Java encounters the same object for serialization it sees that this object has not been serialized to the current ObjectOutputStream and hence it will serialize it again to the new stream.


See following Example:
=========================================
Ser g = new Ser();
Car c1 = new Car(1, g);
Car c2 = new Car(2, g);
ObjectOutputStream out1 = new ObjectOutputStream(
        FileOutputStream(“out1.dat”));
ObjectOutputStream out2 = new ObjectOutputStream(
        FileOutputStream(“out2.dat”));

out1.writeObject(c1);
out2.writeObject(c2);
out1.close();
out2.close();

Now to prove that the Ser object is indeed serialized twice, we read the streams back:

ObjectInputStream in1 = new ObjectInputStream(
        new FileInputStream(“out1.dat”));
ObjectInputStream in2 = new ObjectInputStream(
        new FileInputStream(“out2.dat”));
Car first = (Car) in1.readObject();
Car second = (Car) in2.readObject();
System.out.println(first.getSerType() == second.getSerType());

Now the above code prints false, which proves that the Ser object was serialized twice.
=========================================

Important points to remember:
  • we use Externalizable interface to control serialization as it provides us writeExternal() and readExternal() method which gives us flexibility to control java serialization mechanism instead of relying on Java's default serialization. Correct implementation of Externalizable interface can improve performance of application drastically.
  • Serializable interface exists in java.io  package and forms core of java serialization mechanism. It doesn't have any method and also called Marker Interface in Java. When your class implements java.io.Serializable interface it becomes Serializable in Java and gives compiler an indication that use Java Serialization mechanism to serialize this object.
  • If we don't want any field to be part of object's state then declare it either static or transient based on our need and it will not be included during Java serialization process.
  • If we try to serialize an object of a class which implements Serializable, but the object includes a reference to an non- Serializable class then a NotSerializableException’ will be thrown at runtime and in this case we need to use transient keyword.
  • We all know that for serializing an object ObjectOutputStream.writeObject (saveThisobject) is invoked and for reading object ObjectInputStream.readObject() is invoked but there is one more thing which Java Virtual Machine provides you is to define these two method in your class. If you define these two methods in your class then JVM will invoke these two methods instead of applying default serialization mechanism. You can customize behavior of object serialization and deserialization here by doing any kind of pre or post processing task. Important point to note is making these methods private to avoid being inherited, overridden or overloaded. Since only Java Virtual Machine can call private method integrity of your class will remain and Java Serialization will work as normal.
  • SerialVersionUID is an ID which is stamped on object when it get serialized usually hashcode of object, you can use tool serialver to see serialVersionUID of a serialized object . SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also.  Consequence of not specifying  serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch.
  • Suppose if we have super class which is serialized and then if  we want to avoid serialization for new class of  super class  by  implementing writeObject() and readObject() method in your Class and need to throw NotSerializableException from those method. This is another benefit of customizing java serialization process.
Suppose we have a class which you serialized it and stored in persistence and later modified that class to add a new field then what will happen if you deserialize the object already serialized?

It depends on whether class has its own serialVersionUID or not. If we don't provide serialVersionUID in our code java compiler will generate it and normally it’s equal to hashCode of object. by adding any new field there is chance that new serialVersionUID generated for that class version is not the same of already serialized object and in this case Java Serialization API will throw java.io.InvalidClassException and this is the reason its recommended to have your own serialVersionUID in code and make sure to keep it same always for a single class.

Uses of serialization:
  • To persist data for future use.
  • To send data to a remote computer using such client/server Java technologies as RMI or socket programming.
  • To "flatten" an object into array of bytes in memory.
  • To exchange data between applets and servlets.
  • To store user session in Web applications.
  • To activate/passivate enterprise java beans.
  • To send objects between the servers in a cluster.

TreeMap in JAVA

TreeMap implements the NavigableMap interface and extends the Abstractmap class.
It contains unique elements.
TreeMap contains the value based on the key. It stores values as key value pairs.
It cannot supports null as key but can have null values.
It maintains ascending order.

Following is the hierarchy of hashMap

 Map

  | extends
  |

SortedMap

  | extends
  |

NavigableMap

  | implements
  |

TreeMap

Example:

/**
 * if key is same and content is same for three values then it will
 * print last value like shown below TreeMap may supports null values
 * but key must be not null(using KeySet Method)
 */
Map map1 = new TreeMap();
map1.put("one", "krishna");
map1.put("one", "krishna1");
map1.put("two", "munna");
map1.put("three", "balu");
// map1.put(null, "anusha");
map1.put("four", "tiger");
Set set1 = map1.keySet();
Iterator iterator1 = set1.iterator();
while (iterator1.hasNext()) {
String object = (String) iterator1.next();
System.out.println(map1.get(object));

}

//==============================================

/**
 * if key is same and content is same for three values then it will
 * print last value like shown below TreeMap may supports null values
 * but key must be not null(Using EntrySet Method)
 */
Map map11 = new TreeMap();
map11.put("one", "krishna");
map11.put("one", "krishna1");
map11.put("two", "munna");
map11.put("three", "balu");
map11.put("four", "tiger");
Set set11 = map11.entrySet();
Iterator iterator11 = set11.iterator();
while (iterator11.hasNext()) {
Map.Entry object = (Map.Entry) iterator11.next();
System.out.println(object.getKey() + "}}}}}}}}}}}}}}}"
+ object.getValue());

}

// ==============================================
/**
 * if key is same and content is same for three values then it will
 * print last value like shown below TreeMap may supports null values
 * but key must be not null(Using EntrySet Method). Tree Map supports
 * different types of objects like strings,integers but key must be same
 * other wise exception will raise java.lang.ClassCastException:
 * java.lang.String cannot be cast to java.lang.Integer.
 */
Map map111 = new TreeMap();
map111.put("one", "krishna");
map111.put("one", "krishna1");
map111.put("two", "munna");
map111.put("three", "balu");
map111.put("four", new Integer(9));// integer as value
// map111.put(new Integer(88), new Integer(99));//integer as key not
// support in Tree Map
Set set1411 = map111.entrySet();
Iterator iterator4111 = set1411.iterator();
while (iterator4111.hasNext()) {
Map.Entry object = (Map.Entry) iterator4111.next();
System.out.println(object.getKey()+ "}}}}}}************}}}"+ object.getValue());

}

HashMap in JAVA

HashMap implements the Map interface and extends the Abstractmap class.
It contains unique elements.
Hashmap contains the value based on the key. It stores values as key value pairs.
It supports null as key.
It maintains no order.
It supports multiple null values.

Following is the hierarchy of hashMap

 Map

  | implements
  |

Abstractmap

  | extends
  |

HashMap

Example:

/**
 * if key is different and content is same for three values then it will
 * print all values as shown below example HashMap allows null as key
 * values(Using EntrySet Method)
 */

Map map = new HashMap();
map.put("one", "krishna");
map.put("one1", "krishna");
map.put("two", "munna");
map.put("three", "balu");
map.put("four", "tiger");
map.put(null, null);
map.put(null, null);
map.put(null, "null key3");
Set set = map.entrySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry object = (Map.Entry) iterator.next();
System.out.println(object.getKey() + "*******" + object.getValue());

}

// ==============================================

/**
 * if key is different and content is same for three values then it will
 * print all values as shown below example HashMap allows null as key
 * values(Using KeySet Method)
 */

Map map2 = new HashMap();
map2.put("one", "krishna");
map2.put("one1", "krishna");
map2.put("two", "munna");
map2.put("three", "balu");
map2.put("four", "tiger");
map2.put(null, null);
map2.put(null, null);
map2.put(null, "null key3");
Set set2 = map2.keySet();
Iterator iterator2 = set2.iterator();
while (iterator2.hasNext()) {
Object object = (Object) iterator2.next();
System.out.println(object + "***#############****"
+ map2.get(object));

}

// =============================================
/**
 * if key is different and content is same for three values then it will
 * print all values as shown below example. HashMap allows null as key
 * values(Using KeySet Method).Hash Map supports different types of
 * objects like strings,integers as values and as well as keys.
 */

Map map42 = new HashMap();
map42.put("one", "krishna");
map42.put("one1", "krishna");
map42.put("two", "munna");
map42.put("three", "balu");
map42.put("four", "tiger");
map42.put(null, null);
map42.put(null, null);
map42.put(null, "null key3");
map42.put(new Integer(54), "null key3");// /integer as key
map42.put("integer", new Integer(88));// integer as value
Set set42 = map42.keySet();
Iterator iterator42 = set42.iterator();
while (iterator42.hasNext()) {
Object object = (Object) iterator42.next();
System.out.println(objec+ "****&&&&&&&&&&&&&&&&"+ map42.get(object));

}

TreeSet in JAVA

TreeSet implements NavigableSet interface which extends SortedSet interface.
Treeset does not supports duplicates. So it contains unique elements only.

Following is the hierarchy of HashSet:

Iterable

  | extends
  |

Collection
  
  | extends
  |

 Set

  | implements
  |

SortedSet

  | extends
  |

NavigableSet

  | implements
  |

TreeSet

Example:

/**
 * Tree set supports same types of objects. If we add String it will
 * throw exception java.lang.Integer cannot be cast to java.lang.String
 * Set support duplicate values while adding but it does not iterate
 * through duplicates.
 */

TreeSet set111 = new TreeSet();
set111.add(new Integer(1111));
set111.add(new Integer(155551));
set111.add(new Integer(111));
set111.add(new Integer(1111));// Duplicate value
// set111.add("krishna");
Iterator iterator22 = set111.iterator();
while (iterator22.hasNext()) {
System.out.println("%%%%%%%@@@@@@"+ iterator22.next());

}

/**
 * Tree set will iterate the values in ascending order. Tree set does
 * not supports different types of objects.
 */
Set set22 = new TreeSet();
set22.add("munna");
set22.add("krishna");
set22.add("anusha");
set22.add("kusuma");
Iterator iterator21 = set22.iterator();
while (iterator21.hasNext()) {
System.out.println(iterator21.next());
}

LinkedHashSet in JAVA

The Java Collections Framework provide Java developers with a set of classes and interfaces that makes it easier to handle collections of objects. In a sense Collection's works a bit like arrays, except their size can change dynamically, and they have more advanced behavior than arrays.

A collection is simply an object that groups multiple elements into a single unit. It is also called as a container sometimes.

What Is a Collections Framework?

A collections framework is a unified architecture for representing and manipulating collections. All collections frameworks contain the following:
  • Interfaces: These are abstract data types that represent collections. Interfaces allow collections to be manipulated independently of the details of their representation.
  • Implementations(i.e, Classes): These are the concrete implementations of the collection interfaces.
  • Algorithms: These are the methods that perform useful computations, such as searching and sorting, on objects that implement collection interfaces. The algorithms are said to be polymorphic: that is, the same method can be used on many different implementations of the appropriate collection interface. In essence, algorithms are reusable functionality.

Benefits of the Java Collections Framework:

Reduces programming effort: By providing useful data structures and algorithms, the Collections Framework frees you to concentrate on the important parts of your program rather than on the low-level "plumbing" required to make it work.

Increases program speed and quality: This Collections Framework provides high-performance, high-quality implementations of useful data structures and algorithms. The various implementations of each interface are interchangeable, so programs can be easily tuned by switching collection implementations. Because you're freed from the drudgery of writing your own data structures, you'll have more time to devote to improving programs' quality and performance.

Allows interoperability among unrelated APIs: The collection interfaces are the vernacular by which APIs pass collections back and forth. 

Reduces effort to learn and to use new APIs: Many APIs naturally take collections on input and furnish them as output. In the past, each such API had a small sub-API devoted to manipulating its collections. There was little consistency among these ad hoc collections sub-APIs, so you had to learn each one from scratch, and it was easy to make mistakes when using them. With the advent of standard collection interfaces, the problem went away.

Reduces effort to design new APIs: This is the flip side of the previous advantage. Designers and implementers don't have to reinvent the wheel each time they create an API that relies on collections; instead, they can use standard collection interfaces.

Fosters software reuse: New data structures that conform to the standard collection interfaces are by nature reusable. The same goes for new algorithms that operate on objects that implement these interfaces.

We will update LinkedHashSet class details soon.

HashSet in JAVA

HashSet extends AbstractSet class and implements Set interface.
hashset does not supports duplicates. So it contains unique elements only.

Following is the hierarchy of HashSet:

Iterable

  | extends
  |

Collection
  
  | extends
  |

 Set

  | implements
  |

AbstractSet

  | extends
  |

HashSet

Example:

/**
 * Set does not allow duplicates but if we are trying to add it will
 * supports but it can not iterate through duplicates and also it check
 * the address not the content for duplication. In below example content
 * is same but are adding three different instances of class
 *
 */
Set set1111 = new HashSet();
  // We have BeanExample implementation below of this class.
BeanExample beanExample = new BeanExample();
beanExample.setUserName("krishna");
beanExample.setPassword("krishna");
set1111.add(beanExample);
BeanExample beanExample1 = new BeanExample();
beanExample1.setUserName("krishna");
beanExample1.setPassword("krishna");
set1111.add(beanExample1);
BeanExample beanExample11 = new BeanExample();
beanExample11.setUserName("krishna");
beanExample11.setPassword("krishna");
set1111.add(beanExample11);

System.out.println("@@@@@@@@@@@@@@@@@@@" + set1111.size());
Iterator iterator111 = set1111.iterator();
while (iterator111.hasNext()) {
// System.out.println(iterator.next());
BeanExample beanExample2 = (BeanExample) iterator111.next();
String userName = beanExample2.getUserName();
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$" + userName);
}

/**
 * Hash set supports different types of objects. Set support duplicate
 * values while adding but it does not iterate through duplicates.
 */
HashSet stringSet = new HashSet();
String string = "krishna";
Integer integer = new Integer(8);
stringSet.add(integer);
stringSet.add(integer);
stringSet.add(new Integer(9));
System.out.println("###########################" + stringSet.size());
Iterator iterator1111 = stringSet.iterator();

while (iterator1111.hasNext()) {
System.out.println("%%%%%%%%%%%%%%%%%%%%" + iterator1111.next());
}
stringSet.add(string);
stringSet.add(string);
Iterator stringIterator = stringSet.iterator();
while (stringIterator.hasNext()) {
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
+ stringIterator.next());
}

*************************************************

public class BeanExample {

private String userName = null;
private String password = null;

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

}