Understanding Advance JAVA In One Article

Then there are the answer constructors must have the same name as the class and can not return a value.

They are only called for a single object once for a single object while regular methods could be called many times and it can return a value or can be void.

THIS KEYWORD1.

This keyword is used to refer to a current object.

2.

This is always a reference to the object on which method was invoked.

3.

This can be used to invoke the current class constructor.

4.

This can be passed as an argument to another method.

class Box a{Double width, height, depth;Box (double w, double h, double d){this.

width = w;this.

height = h;this.

depth = d;}}Here the this is used to initialize a member of current object.

Such as, this.

width refers to the variable width of the current object that has invoked the constructor width only refers to the parameter received in constructor i.

e the argument passed while calling the constructor.

A string is probably the most commonly used class in java library.

String class is encapsulated under java.

lang package.

In Java, every string that you create is actually an object of type String.

One important thing to notice about string object is that string objects are immutable that means once a string object is created it cannot be altered.

an object whose state cannot be changed after it is created is known as an immutable object.

String, Integer, Byte, Short, Float, Double and all other wrapper classes objects are immutable.

public class string { final String str; string(String s) { this.

str = s; } public String get() { return str; }}In this example string is an immutable class.

string’s state cannot be changed once it is created.

CREATING A STRING OBJECTA string can be created in a number of ways, here are few ways of creating string object.

String literal is a simple string enclosed in double quotes “ ”.

A string literal is treated as a string object.

String str1 = “hello”;You can also make a string using another string.

String str2 = new String(str1);You can also make it using a new keyword.

String str3 = new String(“Java”);A string can be made using + operator(Concatenation).

String str4 = str1 + str2;orString str5 = “hello” + “java”;Each time you create a String literal, the JVM checks the string pool first.

If the string literal already exists in the pool, a reference to the pool instance is returned.

If a string does not exist in the pool, a new string object is created and is placed in the pool.

String object is stored in a special memory area known as string constant pool inside the heap memory.

CONCATENATING STRINGThere are 2 methods to concatenate two or more string.

Using the concat() method.

string s = “hello”;string str = “java”;string str2 = s.

concat(str);String str1 = “hello”.

concat(“java”); //works with string literals too.

Using the + operator.

string str = “donald”;string str1 = “trump”;string str2 = str + str2;string st = “donald” + “trump”;STRING COMPARISONString comparison can be done in 3 ways:Using the equal () method.

equals() method compares two strings for equality.

Its general syntax is.

boolean equals (object str)it compares the content of the string.

it will return true if the string matches, else return false.

String s = “hell”;String s1 = “hello”;String s2 = “hello”;s1.

equals(s2); //trues.

equals(s1); //flaseUSING == OPERATOR== operator compares two object references to check whether they refer to the same instance.

This also will return true on a successful match.

String s1 = “java”;String s2 = “java”;String s3 = new string (“java”);test(s1 == s2) // truetest (s1 == s3) // falseThe reason for this is because we are creating a new object using the new operator, and thus it gets created in a non-pool memory area of the heap.

s1 is pointing to the String in string pool while s3 is pointing to the String in heap and hence, when we compare s1 and s3, the answer is false.

BY compareTo() METHODcompareTo() method compares values and return an int which tells if the string compared is less than, equal to or greater than the other string.

it compares the String based on natural ordering.

It’s general syntax is.

int comapreTo(String str)STRING CLASS FUNCTIONThe following methods are some of the most commonly used methods of String class.

charAt() function returns the character located at the specified index.

String str = “followme”;Systrm.

out.

println(str.

charAt(2));output will be: lIndex of a String starts from 0, hence str.

charAt(2) means the third character of the String str.

equalsIgnoreCase() determines the equality of two strings, ignoring their cases (upper or lower case doesn’t matter with this function).

String str = “java”;System.

out.

println(str.

equalsIgnorCase(“JAVA”));output: trueindexOf()indexOf() function returns the index of the first occurrence of a substring or a character.

indexOf() method has four forms:int indexOf(String str): It returns the index within this string of the first occurrence of the specified substring.

int indexOf(int ch, int fromIndex): It returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

int indexOf(int ch): It returns the index within this string of the first occurrence of the specified character.

int indexOf(String str, int fromIndex): It returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

public class StudyTonight { public static void main(String[] args) { String str="StudyTonight"; System.

out.

println(str.

indexOf('u')); //3rd form System.

out.

println(str.

indexOf('t', 3)); //2nd form String subString="Ton"; System.

out.

println(str.

indexOf(subString)); //1st form System.

out.

println(str.

indexOf(subString,7)); //4th form }}output: 2, 11, 5, -1length()length() function return the number of character in a String.

String str = “Count me”;System.

out.

println(str.

length());output: 8replace()replace() method replaces occurrences of a character with a specified new character.

String str = "Change me";System.

out.

println(str.

replace('m','M'));output: Change Mesubstring()substring() the method returns a part of the string.

substring() the method has two forms,public String substring(int begin);public String substring(int begin, int end);/* character of begin index is inclusive and character of end index is exclusive.

*/The first argument represents the starting point of the substring.

If the substring() method is called with only one argument, the substring returned, will contain characters from specified starting point to the end of the original string.

But, if the call to substring() method has two arguments, the second argument specifies the endpoint of the substring.

String str = "0123456789";System.

out.

println(str.

substring(4));output: 456789System.

out.

println(str.

substring(4,7));output: 456toLowerCase ()This method returns a string with all lowercase character changed to uppercase.

String str = "abcdef";System.

out.

println(str.

toUpperCase());output : ABCDEFtoString()toString() the method returns the string representation of the object used to invoke this method.

toString() is used to represent any Java Object into a meaningful string representation.

It is declared in the Object class, hence can be overridden by any java class.

(Object class is a superclass of all java classes.

)public class Car { public static void main(String args[]) { Car c = new Car(); System.

out.

println(c); } public String toString() { return "This is my car object"; }}output: This is my car objectWhenever we will try to print an object of class Car, its toString() function will be called.

toString() can also be used with normal string objects.

String str = "Hello World";System.

out.

println(str.

toString());output: Hello WorldNOTE: If we don’t override the toString() method and directly print the object, then it would print the object id.

Example:public class Car { public static void main(String args[]) { Car c = new Car(); System.

out.

println(c); }}studytonight.

Car@15db9742 (here studytonight is a user-defined package).

valueOf()Overloaded version of valueOf() method is present in String class for all primitive data types and for the type object.

valueOf() a function is used to convert primitive data types into Strings.

public class Example{ public static void main(String args[]){ int num = 35; String s1 = String.

valueOf(num); //converting int to String System.

out.

println(s1+"IAmAString"); }}output: 35IAmAStringBut for objects, valueOf() method calls toString() function.

toString() with ConcatenationWhenever we concatenate any other primitive data type, or object of other classes with a String object, toString() function or valueOf() function is called automatically to change the other object or primitive type into a string, for successful concatenation.

int age = 10;String str = "He is" + age + "years old.

";In the above case, 10 will be automatically converted into a string for concatenation using the function.

trim()This method returns a string from which any leading and trailing whitespaces has been removed.

String str = " hello ";System.

out.

println(str.

trim());output: helloNOTE: If the whitespaces are between the string, for example: String s1 = "study tonight"; then System.

out.

println(s1.

trim());will output "study tonight".

trim() method removes only the leading and trailing whitespaces.

StringBuffer classStringBuffer class is used to create a mutable string object that its state can be changed after it is created.

It represents growable and writeable character sequence.

As we know that String objects are immutable, so if we do a lot of changes with String objects, we will end up with a lot of memory leak.

So StringBuffer class is used when we have to make a lot of modifications to our string.

it is also threaded safe that is multiple threads cannot access it simultaneously.

StringBuffer()StringBuffer(int size)StringBuffer(String str)StringBuffer(charSequence []ch)StringBuffer() creates an empty string buffer and reserves room for 16 characters.

stringBuffer(int size) creates an empty string and takes an integer argument to set capacity of the buffer.

DIFFERENCE BETWEEN STRING AND StringBufferclass Test { public static void main(String args[]) { String str = "donald"; str.

concat("trump"); System.

out.

println(str); // Output: donaldStringBuffer strB = new StringBuffer("donald"); strB.

append("trump"); System.

out.

println(strB); // Output: donaldtrump }}Reason:The output is such because String objects are immutable objects.

Hence, if we concatenate on the same String object, it won’t be altered(Output: donald).

But StringBuffer creates mutable objects.

Hence, it can be altered(Output: donaldtrump)append()This method will concatenate the string representation of any type of data to the end of the invoking StringBuffer object.

append() method has several overloaded forms.

StringBuffer append(String str)StringBuffer append(int n)StringBuffer append(Object obj)The string representation of each parameter is appended to the StringBuffer object.

StringBuffer str = new StringBuffer("test");str.

append(123);System.

out.

println(str);output: test123insert()This method inserts one string into another.

Here are a few forms of the insert() method.

StringBuffer insert(int index, String str)StringBuffer insert(int index, int num)StringBuffer insert(int index, Object obj)Here the first parameter gives the index at which position the string will be inserted and a string representation of the second parameter is inserted into StringBuffer object.

StringBuffer str = new StringBuffer("test");str.

insert(4, 123);System.

out.

println(str);output: test123reverse()This method reverses the characters within a StringBuffer object.

StringBuffer str = new StringBuffer("Hello");str.

reverse();System.

out.

println(str);output: olleHreplace()This method replaces the string from the specified start index to the end index.

StringBuffer str = new StringBuffer("Hello World");str.

replace( 6, 11, "java");System.

out.

println(str);output: Hello javacapacity()This method returns the current capacity of the StringBuffer object.

StringBuffer str = new StringBuffer();System.

out.

println( str.

capacity() );output: 16Note: Empty constructor reserves space for 16 characters.

Therefore the output is 16.

ensureCapacity()This method is used to ensure a minimum capacity of StringBuffer object.

If the argument of the ensureCapacity() method is less than the existing capacity, then there will be no change in existing capacity.

If the argument of the ensureCapacity() method is greater than the existing capacity, then there will be a change in the current capacity using the following rule: newCapacity = (oldCapacity*2) + 2.

StringBuffer str = new StringBuffer();System.

out.

println( str.

capacity()); //output: 16 (since empty constructor reserves space for 16 characters)str.

ensureCapacity(30); //greater than the existing capacitySystem.

out.

println( str.

capacity()); //output: 34 (by following the rule – (oldcapacException Handling is the mechanism to handle runtime malfunctions.

We need to handle such exceptions to prevent abrupt termination of the program.

The term exception means an exceptional condition, it is a problem that may arise during the execution of the program.

A bunch of things can lead to exceptions, including programmer error, hardware failure, files that need to be opened cannot be found, resource exhaustion etc.

EXCEPTIONA JAVA exception is an object that describes that occurs in a program.

When an exceptional event occurs in Java, an exception is said to be thrown.

The code that’s responsible for doing something about the exception is called an exception handler.

All exception types are subclasses of class Throwable, which is at the top of the exception class hierarchy.

Exception class is for exceptional conditions that the program should catch.

This class is extended to create user-specific exception classes.

RuntimeException is a subclass of Exception.

Exceptions under this class are automatically defined for programs.

An exception of type Error is used by the Java run-time system to indicate errors having to do with the run-time environment, itself.

EXCEPTIONS ARE CATEGORIZED INTO 3 CATEGORYChecked Exception: The exception that can be predicted by the programmer at the compile time.

Unchecked Exception: Unchecked exceptions are the class that extends RuntimeException.

An unchecked exception is ignored at compile time.

Error: Errors are typically ignored in code because you can rarely do anything about an error.

Uncaught ExceptionsWhen we don’t handle the exceptions, they lead to unexpected program termination.

Let’s take an example for a better understanding.

class UncaughtException{ public static void main(String args[]) { int a = 0; int b = 7/a; // Divide by zero, will lead to exception }}This will lead to an exception at runtime, hence the Java run-time system will construct an exception and throw it.

As we don’t have any mechanism for handling an exception in the above program, hence the default handler will handle the exception and will print the details of the exception on the terminal.

EXCEPTION HANDLING MECHANISMIn JAVA, exception handling is done using five keywords,trycatchthrowthrowsfinallyException handling is done by transferring the execution of a program to an appropriate exception handler when an exception occurs.

USING TRY AND CATCHTry is used to guard a block of code in which exception may occur.

This block of code is called the guarded region.

A catch statement involves declaring the type of exception you are trying to catch.

If an exception occurs in guarded code, the catch block that follows the try is checked, if the type of exception that occurred is listed in the catch block then the exception is handed over to the catch block which then handles it.

class Excp{ public static void main(String args[]) { int a,b,c; try { a=0; b=10; c=b/a; System.

out.

println("This line will not be executed"); } catch(ArithmeticException e) { System.

out.

println("Divided by zero"); } System.

out.

println("After exception is handled"); }}output:Divided by zero After exception is handledAn exception will be thrown by this program as we are trying to divide a number by zero inside try block.

The program control is transferred outside try block.

This the line “this line will not be executed” is never parsed by the compiler.

The exception thrown is handled in the catch block.

Once the exception is handled, the program control continues with the next line in the program that is after the catch block.

Thus the line “after an exception is handled” is printed.

MULTIPLE CATCH BLOCKSA try block can be followed by multiple catch blocks.

You can have any number of catch blocks after a single try block.

If an exception occurs in the guarded code the exception is passed to the first catch block in the list.

If the exception type of exception, matches with the first catch block it gets caught if not the exception is passed down to the next catch block.

This continues until the exception is caught or falls through all catches.

class Excep{ public static void main(String[] args) { try { int arr[]={1,2}; arr[2]=3/0; } catch(ArithmeticException ae) { System.

out.

println("divide by zero"); } catch(ArrayIndexOutOfBoundsException e) { System.

out.

println("array index out of bound exception"); } }}output:divide by zeroAlthough both ArrayIndexOutOfBoundsException and ArithmeticException occurred, since the first catch is of Arithmetic Exception, it will be caught there and program control will be continued after the catch block.

At a time, only once the exception is processed and only one respective catch block is executed.

While using multiple catch statement, it is important to remember that subclasses of class Exception inside catch must come before any of their superclasses otherwise it will lead to compile time error.

This is because in Java, if any code is unreachable, then it gives compile time error.

class Excep{ public static void main(String[] args) { try { int arr[]={1,2}; arr[2]=3/0; } catch(Exception e) //This block handles all Exception { System.

out.

println("Generic exception"); } catch(ArrayIndexOutOfBoundsException e) //This block is unreachable { System.

out.

println("array index out of bound exception"); } }}output:Generic exceptionNESTED TRY STATEMENTtry statement can be nested inside another block of try.

The nested try block is used when a part of the block may cause one error while the entire block may cause another error.

In case of the inner try block does not have a catch handler for a particular exception then the outer try-catch block is checked for a match.

class Excep{ public static void main(String[] args) { try { int arr[]={5,0,1,2}; try { int x=arr[3]/arr[1]; } catch(ArithmeticException ae) { System.

out.

println("divide by zero"); } arr[4]=3; } catch(ArrayIndexOutOfBoundsException e) { System.

out.

println("array index out of bound exception"); } }}output:divide by zero array index out of bound exceptionTry WITH RESOURCE STATEMENTJDK 7 introduces a new version of a try statement known as a try-with-resources statement.

This feature adds another way to exception handling with resources management.

It is also referred to as automatic resource management.

syntax:try(resource-specification(there can be more than one resource)){//use the resource}catch(){.

}This try statement contains a parenthesis in which one or more resources declared.

Any object that implements java.

lang.

AutoCloseable or java.

io.

Closeable can be passed as a parameter to try a statement.

A resource is an object that is used in a program and must be closed after the program is finished.

The try-with-resources statement ensures that each resource is closed at the end of a statement of the try block.

You do not have to explicitly close the resources.

Example without using try with Resource Statementimport java.

io.

*;class Test{public static void main(String[] args){try{String str;//opening file in read mode using BufferedReader streamBufferedReader br=new BufferedReader(new FileReader("d:myfile.

txt"));while((str=br.

readLine())!=null) {System.

out.

println(str); }br.

close(); //closing BufferedReader stream}catch(IOException ie){ System.

out.

println("exception"); } }}Example using try with Resource statementimport java.

io.

*;class Test{public static void main(String[] args){try(BufferedReader br=new BufferedReader(new FileReader("d:myfile.

txt"))){String str;while((str=br.

readLine())!=null){System.

out.

println(str);}}catch(IOException ie){ System.

out.

println("exception"); }}}POINTS TO REMEMBERA resource is an object in a program that must be closed after the program has finished.

Any object that implements java.

lang.

AutoCloseable or java.

io.

Closeable can be passed as a parameter to try a statement.

All the resources declared in the try-with-resources statement will be closed automatically when the try block exits.

There is no need to close it explicitly.

We can write more than one resources in the try statement.

In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.

THROW KEYWORDthrow keyword is used to throw an exception explicitly.

The only object is Throwable class or its subclasses can be thrown.

Program execution stops on encountering throw statement, and the closes catch statement is checked for matching the type of exception.

Syntax: throw ThrowableInstanceCREATING INSTANCE OF THROWABLE CLASSThere are two possible ways to create an instance of class Throwable,Using a parameter in the catch block.

Creating an instance with a new operator.

new NullPointerException("test");This constructs an instance of NullPointerException with name test.

EXAMPLE DEMONSTRATING THROW KEYWORDClass Test{ static void avg() { try { throw new ArithmeticException("demo"); } catch(ArithmeticException e) { System.

out.

println("Exception caught"); } } public static void main(String args[]) { avg(); }}In the above example, the avg() method throws an instance of ArithmeticException, which is successfully handled using the catch statement and thus, the program outputs “Exception caught”.

throws KeywordAny method that is capable of causing exceptions must list all the exceptions, possible during its execution so that anyone calling that method gets a prior knowledge about which exceptions are to be handled.

A method can do so by using the throws keyword.

Syntax:type method_name(parameter_list) throws exception_list{ //definition of method}Example demonstrating throws keyword:class Test{ static void check() throws ArithmeticException { System.

out.

println("Inside check function"); throw new ArithmeticException("demo"); } public static void main(String args[]) { try { check(); } catch(ArithmeticException e) { System.

out.

println("caught" + e); } }}output:Inside check functioncaught java.

lang.

ArithmeticException: demoDIFFERENCE BETWEEN THROW AND THROWSthrow keyword is used to throw an exception explicitly, throws keyword is used to declare an exception possible during its execution.

throw keyword is followed by an instance of Throwable class or one of its sub-classes.

throws keyword is followed by one or more Exception class names separated by commas.

throw keyword is declared inside a method body, throws keyword is used with method signature(method declaration).

We cannot throw multiple exceptions using throw exception, we can declare multiple exceptions (separated by comms) using throws keyword.

FINALLY CLAUSEA finally keyword is used to create a block of code that follows a try block.

A finally block of code is always executed whether an exception has occurred or not.

Using a finally block, it lets you run any cleanup type statement that you want to execute, no matter what happens in the protected code.

A finally block appears at the end of the catch block.

Class ExceptionTest{ public static void main(String[] args) { int a[]= new int[2]; System.

out.

println("out of try"); try { System.

out.

println("Access invalid element"+ a[3]); /* the above statement will throw ArrayIndexOutOfBoundException */ } finally { System.

out.

println("finally is always executed.

"); } }}output: Out of tryfinally is always executed Exception in thread main java.

Lang.

exception array Index out of bound exYou can see in the above example even if the exception is thrown by the program, which is not handled by the catch block, still finally block will get executed.

USER DEFINED EXCEPTION SUBCLASSYou can also create your own exception subclass simply by extending java Exception class.

You can define a constructor for your Exception subclass and you can override the toString() function to display your customized message on a scatch.

class MyException extends Exception { private int ex; MyException(int a) { ex=a; } public String toString() { return "MyException[" + ex +"] is less than zero"; } } class Test { static void sum(int a,int b) throws MyException { if(a<0) { throw new MyException(a); //calling constructor of user-defined exception class } else { System.

out.

println(a+b); } } public static void main(String[] args) { try { sum(-10, 10); } catch(MyException me) { System.

out.

println(me); //it calls the toString() method of user-defined Exception } } }output:MyException[-10] is less than zeroMETHOD OVERRIDING WITH EXCEPTION HANDLINGThere are few things to remember when overriding a method with exception handling.

If the superclass method does not declare any exception, then subclass overridden method cannot declare checked exceptions but it can declare unchecked exceptions.

example of subclass overridden Method declaring Checked Exceptionimport java.

io.

*;class Super{ void show() { System.

out.

println("parent class"); }}public class Sub extends Super{ void show() throws IOException //Compile time error { System.

out.

println("parent class"); } public static void main( String[] args ) { Super s=new Sub(); s.

show(); }}As the method show() doesn’t throw any exception while in the superclass, hence it has overridden version also cannot throw any checked exception.

example of subclass overridden method declaring unchecked exception:import java.

io.

*;class Super{ void show(){ System.

out.

println("parent class"); }}public class Sub extends Super{ void show() throws ArrayIndexOutOfBoundsException //Correct { System.

out.

println("child class"); } public static void main(String[] args) { Super s=new Sub(); s.

show(); }}output:child classBecause ArrayIndexOutOfBoundsException is an unchecked exception hence, overridde show() method can throw it.

MORE ABOUT OVERRIDEN METHOD AND EXCEPTIONSIf the Super class method throws an exception, then the subclass overridden method can throw the same exception or no exception, but must not throw parent exception of the exception thrown by the Super class method.

It means, if the Super class method throws an object of NullPointerException class, then the subclass method can either throw the same exception or can throw no exception, but it can never throw an object of the Exception class.

example of subclass overridden method with the same Exceptionimport java.

io.

*;class Super{ void show() throws Exception { System.

out.

println("parent class"); }}public class Sub extends Super { void show() throws Exception //Correct { System.

out.

println("child class"); } public static void main(String[] args) { try { Super s=new Sub(); s.

show(); } catch(Exception e){} }}output:child classexample of subclass overridden method with no exception:import java.

io.

*;class Super{ void show() throws Exception { System.

out.

println("parent class"); }}public class Sub extends Super { void show() //Correct { System.

out.

println("child class"); } public static void main(String[] args) { try { Super s=new Sub(); s.

show(); } catch(Exception e){} }}output:child classThe exception of the subclass overridden method with parent Exception:import java.

io.

*;class Super{ void show() throws ArithmeticException { System.

out.

println("parent class"); }}public class Sub extends Super { void show() throws Exception //Cmpile time Error { System.

out.

println("child class"); } public static void main(String[] args) { try { Super s=new Sub(); s.

show(); } catch(Exception e){} }}CHAINED EXCEPTIONChained Exception was added to Java in JDK 1.

4.

This feature allows you to relate one exception with another exception, that is one exception describes the cause of another exception.

For example, consider a situation in which a method throws an ArithmeticException because of an attempt to divide by zero bu the actual cause of exception was an input-output error which caused the divisor to be zero.

The method will throw only Arithmetic Exception to the caller.

So the caller would not come to know about the actual cause of the exception.

The chained exception is used in such type of situation.

Two new constructor and two new methods were added to the Throwable class to support chained exception:Throwable (Throwable cause)Throwable (String str, Throwable cause)In the first form, the parameter cause specifies the actual cause of the exception.

In the second form, it allows us to add an exception description in string form with the actual cause of the exception.

getCause() and initCause() are the two methods added to Throwable class.

getCause() method return the actual cause associated with the current exception.

initCause() set an underlying cause with invoking the exception.

EXAMPLE:import java.

io.

IOException;public class ChainedException { public static void divide(int a, int b) { if(b==0) { ArithmeticException ae = new ArithmeticException("top layer"); ae.

initCause( new IOException("cause") ); throw ae; } else { System.

out.

println(a/b); } } public static void main(String[] args) { try { divide(5, 0); } catch(ArithmeticException ae) { System.

out.

println( "caught : " +ae); System.

out.

println("actual cause: "+ae.

getCause()); } }}OUTPUT:caught: java.

lang.

ArithmeticException: top layeractual cause: java.

io.

IOException: causeINTRODUCTION TO MULTITHREADINGA program can be divided into a number of small process.

Each small process can be addressed as a single thread.

You can think of a lightweight process as a virtual CPU that exceeds code or system calls.

You usually do not need to concern yourself with lightweight processess to program with threads.

Multithreaded programs contain two or more threads that can run concurrently and each thread defines a separate path of execution.

This means that single program can perform two task or more tasks simultaneously.

For example, one thread is writing content on a file at the same time another thread is performing spelling check.

In Java, the word thread means two different things:1.

An instance of Thread class.

2.

Or, A thread of execution.

An instance of Thread class is just an object, like any other object in JAVA.

But a thread of execution means an individual “lightweight” process that has its own call stack.

In java each thread has its own call stack.

THE main THREADWhen we run any java program, the program begins to execute its code starting from the main method.

Therefore, the JVM creates to start executing the code present in main methods.

This thread is called a main thread.

Although the main thread is automatically created, you can control it by obtaining a reference to it by calling currentThread() method.

Two important things to know about main thread are,1.

It is the thread from which other threads will be produced.

2.

main thread must be always the last thread to finish execution.

class MainThread{public static void main(String[] args){Thread t=Thread.

currentThread();t.

setName(“MainThread”);System.

out.

println(“Name of thread is “+t);}}Output:Name of thread is[MainThread,5,main]LIFE CYCLE OF A THREAD1.

New: A thread begins its life cycle in the new state.

It remains in this state until the start() method is called on it.

2.

Runnable: After invocation of start() method on new thread, the thread becomes runnable.

3.

Running: A thread is in running state if the thread scheduler has selected it.

4.

Waiting: A thread is in waiting state if it waits for another thread to perform a task.

In this stage the thread is still alive.

5.

Terminated: A thread enter the terminated state when it completes its task.

THREAD PRIORITIESEvery thread has a priority that helps the operating system determine the order in which threads are scheduled for execution.

In Java thread priority ranges between 1 to 10.

1.

MIN-PRIORITY (a constant of 1 )2.

MAX-PRIORITY(a constant of 10)By default every thread is given a NORM-PRIORITY(5).

The main thread always have a non-priority.

THREAD CLASSThread class is the main class on which Java’s Multithreading system is based.

Thread class, along with its companion interface Runnable will be used to create and run threads for utilizing Multithreading feature of JAVA.

CONSTRUCTOR OF THREAD CLASS1.

Thread ()2.

Thread (String str)3.

Thread(Runnable r)4.

Thread(Runnable r, string str)You ca create new thread, either by extending Thread class or by implementing Runnable interface.

Thread class also defines many methods for managing threads.

Some of them are,1.

setName(): to give thread a name2.

getName(): return thread’s name3.

getPriority(): return thread’s priority4.

isAlive(): checks if thread is still running or not5.

join(): wait for a thread to end6.

run(): entry point for a thread7.

sleep(): suspend thread for a specified time8.

start(): start a thread by calling run() methodSOME IMPORTANT POINTS TO REMEMBER1.

when we execute Thread class, we cannot override setName() and getName() functions, because they are declared final in Thread class.

2.

While using sleep(), always handle the exception it throws.

static void sleep(long milliseconds) throws InterruptedExceptionCREATING A THREADJava defines two ways by which a thread can be created.

1.

By implementing the Runnable interface.

2.

By extending the Thread class.

IMPLEMENTING THE RUNNABLE INTERFACEThe easiest way to create a thread is to create that implements the runnable interface.

After implementing runnable interface, the class needs to implement the run() method, which is of form.

Public void run()1.

Run() method introduces a concurrent thread into your program.

This thread will end when run() method terminates.

2.

You must specify the code that your thread will execute inside run() method.

3.

Run() method can call other methods, can use other classes and declare variables just like any other normal method.

class MyThread implements Runnable{public void run(){System.

out.

println("concurrent thread started running.

");}}class MyThreadDemo{public static void main( String args[] ){MyThread mt = new MyThread();Thread t = new Thread(mt);t.

start();}}Output:Concurrent thread started running.

To call the run() method, start() method is used.

On calling start(), a new stack is provided to the thread and run() method is called to introduce the new thread into the program.

If you are implementing runnable interface in your class, then you need to explicitly create a thread class object and need to pass the Runnable interface implemented class object as a parameter in its constructor.

EXTENDING THREAD CLASSThis is another way to create a thread by a new class that extends Thread class and create an instance of that class.

The extending class must override run() method which is the entry point of new thread.

class MyThread extends Thread{public void run(){System.

out.

println("concurrent thread started running.

");}}classMyThreadDemo{public static void main( String args[] ){MyThread mt = new MyThread();mt.

start();}}Output:Concurrent thread started running.

In this case also, we must override the run() and then use the start() method to run the thread.

Also, when you create MyThread class object, thread class constructor will also be invoked, as it is the super class, hence MyThread class object acts as Thread class object.

What if we call run() method directly without using start() method?In above program if we directly call run() method, without using start() method.

public static void main( String args[] ){MyThread mt = new MyThread();mt.

run();}Doing so, the thread won’t be allocated a new call stack, and it will start running in the current call stack, that is the call stack of the main thread.

Hence Multithreading won’t be there.

CAN WE START THREAD TWICE?No, a thread cannot be started twice.

If you try to do so.

IllegalThreadException will be thrown.

public static void main( String args[] ){MyThread mt = new MyThread();mt.

start();mt.

start(); //Exception thrown}When a thread is in running stable, and you try to start it again, or any method try to invoke that thread again using start() method, exception is thrown.

JOINING THREADSSometimes one thread needs to know when other thread is terminating.

In JAVA, isAlive() and join() are two different methods that are used to check whether a thread has finished its execution or not.

This isAlive() method returns true if the thread upon which it is called is still running otherwise it returns false.

final boolean isAlive()but, join() method is used more commonly that isAlive().

This method waits until the thread on which it is called terminates.

final void join() throws InterruptedExceptionUsing join() method, we tell our thread to wait until the specified thread completes its execution.

There are overloaded versions of join() method, which allows us to specify time for which you want to wait for the specified thread to terminate.

final void join(long milliseconds) throws InterruptedExceptionAs we have seen in the introduction, the main thread must always be the last thread to finish its execution.

Therefore, we can use thread join() method to ensure that all the threads created by the program has been terminated before the execution of the main thread.

Example of isAlive()public class MyThread extends Thread{public void run(){System.

out.

println("r1 ");try {Thread.

sleep(500);}catch(InterruptedException ie) { }System.

out.

println("r2 ");}public static void main(String[] args){MyThread t1=new MyThread();MyThread t2=new MyThread();t1.

start();t2.

start();System.

out.

println(t1.

isAlive());System.

out.

println(t2.

isAlive());}}Output:r1truetruer1r2r2example of thread without join() methodpublic class MyThread extends Thread{public void run(){System.

out.

println("r1 ");try {Thread.

sleep(500);}catch(InterruptedException ie){ }System.

out.

println("r2 ");}public static void main(String[] args){MyThread t1=new MyThread();MyThread t2=new MyThread();t1.

start();t2.

start();}}Output:r1r1r2r2In this above program two thread t1 and t2 are created.

t1 starts first and after printing “r1” on console thread t1 goes to sleep for 500 ms.

At the same time Thread t2 will start its process and print “r1” on console and then go into sleep for 500 ms.

Thread t1 will wake up from sleep and print “r2” on console similarly thread t2 will wake up from sleep and print “r2” on console.

So you will get output like r1 r1 r2 r2Example of thread with join() methodpublic class MyThread extends Thread{public void run(){System.

out.

println("r1 ");try {Thread.

sleep(500);}catch(InterruptedException ie){ }System.

out.

println("r2 ");}public static void main(String[] args){MyThread t1=new MyThread();MyThread t2=new MyThread();t1.

start();try{t1.

join(); //Waiting for t1 to finish}catch(InterruptedException ie){}t2.

start();}}Output:r1r2r1r2In this above program join() method on thread t1 ensures that t1 finishes it process before thread t2 starts.

Specifying time with join()If in the above program, we specify time while using join() with t1, then t1 will execute for that time, and then t2 will join it.

t1.

join(1500);Doing so, initially t1 will execute for 1.

5 seconds, after which t2 will join it.

SYNCHRONIZATIONAt times when more than one thread try to access a shared resource, we need to ensure that resource will be used by only one thread at a time.

The process by which this is achieved is called synchronization.

The synchronization keyword in java creates a block of code referred to as critical section.

General syntax:synchronized (object){//statement to be synchronized}Every java object with a critical section of code gets a lock associated with the object.

To enter critical section a thread need to obtain the corresponding object’s lock.

WHY WE USE SYNCHRONIZATION?If we do not use syncronization, and let two or more threads access a shared resource at the same time, it will lead to distorted results.

Consider an example, suppose we have two different threads T1 and T2, T1 starts execution and save certain values in a file temporary.

txt which will be used to calculate some result when T1 returns.

Meanwhile, T2 starts and before T1 returns, T2 changes the value saved by T1 in the file temporary.

txt.

Now obviously T1 will return wrong result.

To prevent such problem, synchronization was introduced.

With synchronization in above case, once T1 starts using temporary.

txt file, this file will be locked, and no other thread will be locked, and no other thread will be able to access or modify it until T1 returns.

USING SYNCHRONIZED METHODSUsing synchronized methods is a way to accomplish synchronization.

But lets first see what happens when we do not use synchronization is our program.

Example with no synchronizationclass First{public void display(String msg){System.

out.

print ("["+msg);try{Thread.

sleep(1000);}catch(InterruptedException e){e.

printStackTrace();}System.

out.

println ("]");}}class Second extends Thread{String msg;First fobj;Second (First fp,String str){fobj = fp;msg = str;start();}public void run(){fobj.

display(msg);}}public class Syncro{public static void main (String[] args){First fnew = new First();Second ss = new Second(fnew, "welcome");Second ss1= new Second (fnew,"new");Second ss2 = new Second(fnew, "programmer");}}Output:[welcome [ new [ programmer]]]In the above, object fnew of class First is shared by all three running threads(ss, ss1 and ss2) to call the shared method(void display).

Hence the result is unsynchronized and such situation is called Race condition.

SYNCHRONIZED KEYWORDTo synchronized above program, we must synchronize access to the shared display() method, making it available to only one thread at a time.

This is done by using keyword synchronized with display() method.

As synchronized void display(String msg)USING SYNCHRONIZED BLOCKIf you have to synchronized access to an object of a class or you only want a part of a method to be synchronized to an object then you can use synchronized block for it.

class First{public void display(String msg){System.

out.

print ("["+msg);try{Thread.

sleep(1000);}catch(InterruptedException e){e.

printStackTrace();}System.

out.

println ("]");}}class Second extends Thread{String msg;First fobj;Second (First fp,String str){fobj = fp;msg = str;start();}public void run(){synchronized(fobj) //Synchronized block{fobj.

display(msg);}}}public class Syncro{public static void main (String[] args){First fnew = new First();Second ss = new Second(fnew, "welcome");Second ss1= new Second (fnew,"new");Second ss2 = new Second(fnew, "programmer");}}Output:[welcome][new][programmer]Because of the synchronized block, this program gives the expected output.

DIFFERENCE BETWEEN SYNCHRONIZED KEYWORD AND SYNCHRONIZED BLOCKWhen we use synchronized keyword with a method, it acquires a lock in the object for the whole method.

It means that no other thread can use any synchronized method until the current thread, which has invoked it’s synchronized method, has finished its execution.

Synchronized block acquires a lock in the object only between parentheses after the synchronized keyword.

This means that no other thread can acquire a lock on the locked object until the synchronized block exists.

But other threads can access the rest of the code of the method.

INTERHREAD COMMUNICATIONJava provide benefits of avoiding thread pooling using inter-thread communication.

The wait(), notify() and notifyAll() methods of Object class are used for this purpose.

These methods are implemented as final methods in Object, so that all classes have them.

All the three methods can be called only from within a synchronized context.

1.

Wait() tells calling thread to give up monitor and go to sleep until some other thread enters the same monitor and call notify.

2.

Notify() wakes up a thread that called wait() on same object.

3.

notifyAll() wakes up the thread that called wait() on same object.

DEADLOCKDeadlock is a situation of complete lock, when no thread can complete its execution because of lack of resources.

Example of deadlockclass Pen{}class Paper{}public class Write {public static void main(String[] args){final Pen pn =new Pen();final Paper pr =new Paper();Thread t1 = new Thread(){public void run(){synchronized(pn){System.

out.

println("Thread1 is holding Pen");try{Thread.

sleep(1000);}catch(InterruptedException e){}synchronized(pr){ System.

out.

println("Requesting for Paper"); }}}};Thread t2 = new Thread(){public void run(){synchronized(pr){System.

out.

println("Thread2 is holding Paper");try{Thread.

sleep(1000);}catch(InterruptedException e){}synchronized(pn){ System.

out.

println("requesting for Pen"); }}}};t1.

start();t2.

start();}}Output:Thread1 is holding PenThread2 is holding Paper.

. More details

Leave a Reply