Unit 1 : Java Programming Basics
hitarth's Vault // Exported at - 12:29 AM
We'll cover :
James Gosling and his team started JAVA. In Sun Micro Systems, the JAVA was evolved in the year 1991. The first name of JAVA was OAK.
After 4 years that is in 1995 the first version of JAVA was developed. The name of the version was JAVA alpha Beta version. In 1996 the next version was developed, JDK 1.0.
Version | Release Date | Code Name | |
---|---|---|---|
JDK 1.0 | 1996 | Oak Changed to JAVA | |
JDK 1.1 | DIY | DIY |
JAVA is platform independent
The program written once can run anywhere.
Java is portable since we can move .class
file from one platform to another.
.class
file contains bytecode.
To execute Java code, you need to compile it. The Java compiler (javac
) takes the source code (.java
files) and produces bytecode, which is a platform-independent intermediate representation of the code.
Security :
- JVM : Its basic role is to verify byte code before running it. This makes sure that the program is not making any unsafe operation. There are various unsafe operations that a program can perform, for e.g. A program might branch to an incorrect location that contains data rather than instructions.
- Security Manager : Security Manager Layer is present in JVM, it's makes sure that untrusted code does not manage to access some APIs and features of the platform.
- No Pointers : Java does not support pointers as C and C++ supports, therefore some arbitrary location can not be addressed. Some arbitrary address can be accessed via pointers, which might be
- Java has 4 access modifiers, public, protected, private and default, so if we want to hide some code we can use access modifiers.
Exception Handling :
Own Memory Management :
They are of two types : Primitive and Non-Primitive.
Non Primitive are user defined and Primitive are pre defined
false
.boolean flag = false;
System.out.println(flag);
0
float marks = 98.67f;
long largeIntegerNumbers = 1212514513452234234L;
package com.hitarth;
public class Primitives {
public static void main(String[] args) {
// String is not a primitive
// Primitive is basically a data type that you cannot break further
// Primitives :
int rollno = 64;
char letter = 'r';
float marks = 98.67f; // TN: that we have to add 'f' here.
double largeDecimalNumbers = 456234.3234234;
long largeIntegerNumbers = 1212514513452234234L; // TN: we have to add 'L' here.
boolean check = false;
// 1.) by default all the decimal values are of type double if we want to store these decimal values in lets say 'float' then we have to add 'f' at the end like this : `float marks = 98.67f;`
// 2.) by default all the integer values are of type integers, if we want to store these integers in let's say 'long' then we'll have to add 'L' at the end like this : `long largeIntegerNumbers = 1212514513452234234L;`
}
}
package com.hitarth.classLectures;
public class asd {
public static void main(String[] args) {
char letter1 = '9';
System.out.println(letter1); // → 9
char letter2 = 65; // ASCII / Unicode
System.out.println(letter2); // → A
int number = 'A';
System.out.println(number); // -> 65 // ASCII value of A = 65
}
}
String a = "Kunal"; // takes 5*2 = 10 bytes
String b = "Kunal";
Kunal Kushwaha dekh le bhai
Variables are of three types : Local, Static and Instance (Global variable) Variables.
Static padhle bhai
package com.hitarth.classLectures;
public class asd {
public static void main(String[] args) {
int a = 10; // instance variable
Static int b =20; // static variable
}
void add()
{
int c =30, d; // local variable
d= a+b+c;
System.out.println(d);
}
void multiply()
{
int e =40, f;
f=a*b*c*e;
System.out.println(f);
}
}
package com.hitarth.packages;
public class random {
}
class A {
int a = 10;
static int b = 20;
void add() {
int c = 30, d; // int c, d => local variable
d = a + b + c;
System.out.println(d);
}
}
NULL
..class
file is loaded.class
file is unloaded the variables get deleted.package com.hitarth.packages;
class abc {
int a = 10;
static int b =20;
}
public class random {
public static void main(String[] args) {
abc ob1 = new abc();
System.out.println(ob1.a); // → 10
System.out.println(ob1.b); // → 20
ob1.a = 1000;
ob1.b = 2000;
System.out.println(ob1.a); // → 1000
System.out.println(ob1.b); // → 2000
abc ob2 = new abc();
System.out.println(ob2.a); // → 10
System.out.println(ob2.b); // → 2000
}
}
Operators are special symbols which can perform any operations on one or more operands.
c = a + b
: a and b are operands%
, increment ++
, decrement --
==
, not equal to !=
, >
, <
, >=
, <=
, &&
in java>>
, bitwise left shift <<
, zero fill right shift >>>
and &&
, or ||
, not !
package com.hitarth.packages;
public class random {
public static void main(String[] args) {
int x = 10, y = -10;
System.out.println(x << 2); // → 40
System.out.println(x >> 2); // → 2
System.out.println(x >>> 2); // → 2
System.out.println(y << 2); // → -40
System.out.println(y >> 2); // → -3
System.out.println(y >>> 2); // → 1073741821
}
}
A value assigned to a variable is known as literals. int a = 10
, literal = 10, variable = a, int = data type.
In Java, keywords are reserved words that have a specific meaning and cannot be used as identifiers (e.g., variable names, class names, method names).
abstract
assert
boolean
break
byte
case
catch
char
class
const
(not used, reserved for future use)continue
default
do
double
else
enum
(introduced in Java 5)extends
final
finally
float
for
if
goto
(not used, reserved for future use)implements
import
instanceof
int
interface
long
native
new
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while
int a =10;
: a
is a variable name = Identifierclass Abc{...};
: Abc
here is an identifier In Java, identifiers are used to name classes, methods, variables, and other program elements. Here are the rules for defining identifiers in Java:
$
), or underscore (_
).myVariable
and myvariable
would be considered different identifiers.three words are given : my java demo
my_java_demo
myJavaDemo
Use Camel Case
my()
myJavaDemo()
MyJavaDemo{}
It is a process of wrapping data and method together into a single unit.
In OOP we have to build objects, and objects are developed by means of classes. Defining classes in OOP is termed as encapsulation.
Telusko YT > Inheritance
Inheritance in JAVA is a mechanism in which one object acquires all the properties and behavior of a parent object.
It is a process of hiding some data or method, so that it is not easily accessible to others.
https://www.geeksforgeeks.org/difference-between-compile-time-and-run-time-polymorphism-in-java/
Function having same name, but it performs different operations.
For example : If we use print operation then, method for printing an image and document will be different.
@Override
use karke uska method ko override karna (@Override
use karna is not necessary))CMD ke through java program run and save karna padhle bhai
Java program normally executes from top to bottom, but if you want to control the order of execution of the program based on some logic and values we use control statements.
Control statements are of three types :
if
, if else
,else if
, nested if
, switch case
for
, while
, do while
return
, break
, continue
Array is a collection of finite set of elements of same type.
Three steps are to be followed to create an array :
Declaration of an array
<type> array_name[]
: int a[]
or int[] a
Allocate memory for an array
<arrayName> = new <type>[size]
: here new
is used to allocate memoryint a[] = new int[100]
or int a[]
then do a = new int[100]
;Initialization of an array.
int a[] = {1,2,3,4,5}
a.length
will give the length of the array
int a[][] = new int[2][3]
int a[2][3] = {1,2,3,4,5,6}
: 1 2 3
4 5 6
package com.hitarth.IIITL2024;
// factorial by recusrion
public class FactorialByRecursion {
public static void main(String[] args) {
int num = 5;
System.out.println("Factorial of " + num + " is: " + factorial(num));
}
static int factorial(int num) {
if (num == 0 || num == 1)
return 1;
else
return num * factorial(num - 1);
}
}
int[]a, b; //-> a-> 1D array, b->1D array
int a[], b; // a-> 1D array, b-> variable
a = new int[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
int[] a = {1,2,3,4,5};
// or
int[] a = new int[]{1,2,4};
int[][] arr;
int arr2[][];
int[]a[];
int[]a, b[]; // → a is 1D array, and b is a 2D array
int[] a[], b[]; // → both are 2D arrays
int[][] a, b[]; // → a is 2D and b is 3D array
int[][]a;
a= new int[2][3];
int[][]a = {{1,2,3},{4,5,6}};
int[][] a;
a = new int[2][];
a[0] = new int[4];
a[1] = new int[2];
// this jagged array will look like this :
// x x x x
// x x
// doing all of this in a single line :
int[][] b = {{1, 2, 3, 4}, {1, 2}};
// 3D Jagged Array :
int[][][]a;
a=new int[2][][];
a[0] = new int[2][];
a[0][0] = new int[3];
a[0][1] = new int[2];
a[1] = new int[2][];
a[1][0] = new int[2];
a[1][1] = new int[3];
package com.hitarth.IIITL2024;
public class temp {
public static void main(String[] args) {
int[][] arr = {{1,2,3,4}, {1,2}};
System.out.println(arr[0].length); // → 4
}
}
package com.hitarth.IIITL2024;
import java.util.Arrays;
public class temp {
public static void main(String[] args) {
int[][] arr = {{9, 8}, {1,2,3,4}};
for(int i =0; i<arr.length; i++)
{
for(int j = 0; j<arr[i].length; j++)
{
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
3D Array :
package com.hitarth.IIITL2024;
import java.util.Arrays;
public class temp {
public static void main(String[] args) {
int[][][] arr = {{{20, 30}, {10, 40, 60}}, {{80, 25}, {76, 23, 44}} };
for(int i=0; i< arr.length; i++)
{
for(int j = 0; j< arr[i].length; j++)
{
for(int k = 0; k< arr[i][j].length; k++)
{
System.out.print(arr[i][j][k] + " ");
}
System.out.println();
}
System.out.println();
}
}
}
No. of rounds = no. of elements in an array - 1
| 36 19 29 12 5<
=> 5 | 19 29 12< 36
=> 5 12 | 29 19< 36
=> 5 12 19 | 29< 36
=> 5 12 19 29 36
2 Lectures missed
package com.hitarth.packages;
/* ------------------------------------------------------ */
//superclass or parent class
class Calc {
public int add(int n1, int n2) {
return n1 + n2;
}
public int sub(int n1, int n2) {
return n1 - n2;
}
}
//subclass or child class
class AdvCalc extends Calc
{
public int mult(int n1, int n2)
{
return n1*n2;
}
}
/* ------------------------------------------------------ */
public class _07_Inheritance {
public static void main(String[] args) {
Calc obj = new Calc();
int r1 = obj.add(1,2);
System.out.println(r1); // → 3
AdvCalc obj2 = new AdvCalc();
int r2 = obj2.mult(2,3);
int r3 = obj2.add(1,3);
System.out.println(r2); // → 6
System.out.println(r3); // → 4
}
}
AdvCalc
IS-A
(read as "is a") Calc
: means that AdvCalc
is a child class and Calc
is a parent class.
IS-A
relationshipexample khud se padh lena bhai
example khud se padh lena bhai
When any two inheritance types are combined :
Only 1,2,3 types of inheritances are used in JAVA.
Inheritance : Is - a
relationship
class Animal
{
}
class Dog extends Animal
{
}
Association : Has - a
relationship
class Student
{
string name;
int roll_no;
}
Student
HAS-A
roll_no
, Student
HAS-A
name
class Engine
{}
class Car
{
psvm()
{
Engine ob1 = new Engine();
}
}
Car
HAS-A
Engine
The difference b/w the two is tight coupling
has-a
relationships.Compile Time Polymorphism : Method Overloading
Run Time Polymorphism : Method Overriding
package com.hitarth;
import java.util.Arrays;
public class temp {
public static void main(String[] args) {
fun(67); // → 67
fun("hello!"); // → hello!
}
static void fun (int a)
{
System.out.println(a);
}
static void fun (String b)
{
System.out.println(b);
}
}
Q : Can we achieve method overloading in JAVA by changing the return type of the method only :
No
Q : Can we Overload the main method of JAVA
Yes
https://www.scaler.com/topics/can-we-overload-main-method-in-java/
https://www.digitalocean.com/community/tutorials/command-line-arguments-in-java
We can have any number of main
methods in a class
by method overloading. JVM always calls main
method, which receives string
array as argument (string args[]
).
If one method is of int
type and other is of string
type and we call these overloaded methods with a char value
. Then it won't show any errors but instead char
value will be promoted to int
value and the int
This works outside of method overloading as well :
package tempPackage;
public class promotion {
public static void printInt(int value) {
System.out.println("Integer value: " + value);
}
public static void main(String[] args) {
char c = 'A'; // Unicode value of 'A' is 65
int i = 10;
// Call printInt method with char argument
// Char will be promoted to int automatically
printInt(c); // Output: Integer value: 65
// Call printInt method with int argument
printInt(i); // Output: Integer value: 10
}
}
package tempPackage;
public class promotion {
void show(int a, float b) {
System.out.println("1");
}
void show(float a, int b){
System.out.println("2");
}
public static void main(String[] args) {
promotion obj = new promotion();
obj.show(1, 34.30f); // → 1
obj.show(1, 5); // error
}
}
float double and long hai methods me to if we pass an
integer
value to wo float double long me se kisko call karega ?
It means methods with same name but in different classes.
package com.hitarth.packages;
class A
{
public void show()
{
System.out.println("in A show");
}
public void config()
{
System.out.println("in A config");
}
}
class B extends A
{
// method overriding
public void show()
{
System.out.println("in B show");
}
}
public class _08_Overriding {
public static void main(String[] args) {
B obj = new B();
obj.show(); // → in B show
obj.config(); // → in A config
}
}
super()
.// child class ka method :
@Override
void show()
{
super.show(); // calls the method of the parent class
System.out.println("Child Class"); //prints "Child Class"
}
Detail / Implementation Hiding : Abstraction
Data hiding : Encapsulation
In this lecture we will learn:
- What is Abstraction?
- Abstract method in Java
- Abstract class in Java
- Abstract vs Concrete classes
#1
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
#2
Abstract method:-
- Instead of defining the method, we can declare the method.
- If we put a semicolon at the end of a method, it means that you only declare the method like:
public void drive();
- This method does not contain any features and you will not be able to create an object of it.
- You need to add an abstract keyword to only declare a method.
#3
Abstract class:-
- Abstract methods can only be defined in an abstract class.
- We need to add an abstract keyword before a class to make it an abstract class.
- Objects of an abstract class can not be created.
- If you are extending an abstract class, then it is compulsory to define all abstract methods.
- It is not necessary that an abstract class should have an abstract method.
- Abstract class can have an abstract or a normal method or both.
- An abstract class can have more than one abstract method.
#4
Concrete class: A class other than an abstract class is known as a concrete class.
- An object of a concrete class can be created.
A method without body (no implementation) is known as an abstract method.
An abstract method must always be declared inside of an Abstract class, or we can say that if a class has an abstract method it should be declared abstract as well
It is not necessary that an abstract class will have abstract methods only, we can create simple methods too which has a defined body.
If a child class extends an abstract class then the class must have to implement all the abstract methods of the abstract parent class or it has to be declared abstract as well.
Interfaces can be used to implement abstraction as well.
Abstraction in JAVA can be implemented in two ways :
In interfaces all the methods are abstract.
They are used to achieve abstraction. It is a blueprint of the class, in which all the methods are abstract and all methods are public.
public static final
keywordpublic static
keyword before a method in an interface.implements
keyword is used when a class inherits the methods of an interface.implements
kar sakte hai ek class me.The reason behind this is to prevent ambiguity. Consider a case where class B extends class A and Class C and both class A and C have the same method display(). Now java compiler cannot decide, which display method it should inherit. To prevent such situation, multiple inheritances is not allowed in java.
interface Interface1 {
void method();
}
interface Interface2 {
void method();
}
class MyClass implements Interface1, Interface2 {
@Override
public void method() {
System.out.println("Implemented method");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.method(); // Output: Implemented method
}
}
MyClass
implements both Interface1
and Interface2
, each of which declares a method method()
. MyClass
provides a single implementation for method()
that satisfies both interfaces. When you call method()
on an instance of MyClass
, the implemented method is invoked, and you get the output "Implemented method"
.this
keyword :this()
can be used to invoke current class constructors.this
keyword can be used to pass as an argument in the method callthis
keyword can be used to pass as an argument in the constructor callClass Test
{
int i;
void start(int a)
{
i = a;
}
void display()
{
sop(i);
}
}
Class Test
{
psvm()
{
Test ob = new Test();
ob.start(10);
ob.display(); // Prints : 10
}
}
Class Test
{
int i;
void start(int a)
{
this.i = i;
}
void display()
{
sop(i);
}
}
This keyword can be used to invoke current class methods
Class ThisDemo
{
void Display()
{
}
void show()
{
}
}
Class Test
{
psvm()
{
ThisDemo ob = new ThisDemo();
ob.Display(); // Here we are "Directly Calling" the a method from ThisDemo Class/Object.
}
}
this()
can be used to invoke current class constructors.
Class A
{
A() // No Arg Constructor
{
this(10); // calls the parameterized constructor
}
A(int a) // Parameterized constructor
{
this(); // will call the No Arg Constructor
sout(a + "parameterized constructor");
}
}
// ---
psvm()
{
A ob = new A(); // invokes the constructor of class A which in turn invokes the parameterized constructor with parameter value 10.
}
this
Keyword can be used to pass as an argument in the method call
method1()
{
}
method2()
{
method1(this)
}
Super
Keyword :Class A
{
int a = 10;
}
Class B extends A
{
int a = 20;
void Dipslay(int a)
{
sout(a); // 30
sout(this.a); // 20
sout(super.a); // 10
}
}
// ---
psvm()
{
B ob = new B();
ob.Dsiplay(30);
}
super()
can be used to invoke immediate parent class constructor.Class A
{
m1()
{
sout("Class A");
}
}
Class B extends A
{
m1()
{
sout("Class B");
}
void Display()
{
m1(); // Prints : Class B
super.m1(); // Prints : Class A
}
}
// --
psvm()
{
B ob = new B();
ob.Display();
}
final
can not be overridden.final
can't be extended.Class A
{
static int a = 10; // instance variable
void Display()
{
int b = 10; // Local Variable
}
}
static void Display()
.sout(A.a)
.class name
.this
and super
keywords in any wayClass test
{
static {
sout("static block");
}
psvm() {
sout("Main Method");
}
}
Output : static block Main Method
try-catch
, finally
, throw
, throws
Class tes
{
psvm()
{
sout("1");
sout("2");
sout("3");
sout("100/2"); // suppose it was (100/0) instead then the compiler will show us an exception
sout("4");
sout("5");
sout("6");
}
}
ClassNotFoundException
, NoSuchMethodException
, IOException
, SQLException
, RemoteException
, InterruptedException
, RuntimeException
, VirtualMachineException
, LinkageError
, AssertionError
IOException
has child classes : EOFException
(end of file), FileNotFoundException
, InterruptedIOException
RuntimeException
: ArithmeticException
, ClassCastException
, NullPointException
, IndexOutOfBoundException
, IllegalArgumentException
VirtualMachineException
: StackOverflowError
, OutOfMemoryError
LinkageError
: VerifyError
, ClassFormatError
, NoClassDefFoundError
Try Block:
try
block encloses the code that may generate exceptions.catch
blocks.try
block, the execution of the try
block is halted, and the control is transferred to the corresponding catch
block.Catch Block:
catch
block catches and handles exceptions thrown within the associated try
block.catch
block specifies the type of exception it can handle, allowing for selective exception handling.catch
block is executed.catch
block matches the thrown exception, it propagates up the call stack, potentially halting the program if unhandled.try {
// Code that may throw exceptions
} catch (ExceptionType1 e1) {
// Exception handling for ExceptionType1
} catch (ExceptionType2 e2) {
// Exception handling for ExceptionType2
} finally {
// Optional: Code that always executes, regardless of exceptions
}
Finally Block:
finally
block can be used after all catch
blocks.finally
block executes whether an exception occurs or not.Example:
try {
int result = 10 / 0; // This will throw an ArithmeticException
} catch (ArithmeticException e) {
System.out.println("An error occurred: " + e.getMessage());
} finally {
System.out.println("This code always executes.");
}
public class Example {
public static void main(String[] args) {
try {
// Creating and throwing a NullPointerException with a "custom" esxception explicitly
throw new NullPointerException("Custom NullPointerException message");
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e.getMessage());
}
}
}
Difference between throw
and throws
:
throw:
throw
is a keyword used to explicitly throw an exception from within a method or block of code.throw
, you can throw both built-in exceptions provided by Java (such as NullPointerException
, IllegalArgumentException
, etc.) and custom exceptions that you define in your code.throw
an exception, you are responsible for creating and specifying the exception object to be thrown.Example:
public void method() {
if (condition) {
throw new SomeException("Custom message");
}
}
throws:
throws
is used in the method declaration to indicate that the method may throw certain types of exceptions during its execution.throws
, you are declaring the exceptions that can be thrown by a method, allowing the caller of the method to handle those exceptions.Example:
public void method() throws SomeException {
// Method code that may throw SomeException
}
The caller of this method would then need to handle the SomeException
either by catching it or declaring it to be thrown further.
In summary, throw
is used to throw an exception explicitly within a method, while throws
is used to declare the types of exceptions that a method might throw, allowing the caller to handle them appropriately.
In Java, you can create your own custom exceptions by extending the built-in Exception
class or one of its subclasses. Here's how you can create and use a custom exception:
Create Custom Exception Class:
First, create a new class that extends Exception
or one of its subclasses. You can define constructors and methods specific to your custom exception.
public class CustomException extends Exception {
public CustomException() {
super("Custom exception message");
}
public CustomException(String message) {
super(message);
}
}
Throw Custom Exception:
In your code, when you encounter a situation that warrants throwing your custom exception, use the throw
keyword followed by an instance of your custom exception class.
public void someMethod() throws CustomException {
// Condition that triggers the exception
if (condition) {
throw new CustomException("Custom message for the exception");
}
}
Handle Custom Exception:
When calling the method that can throw your custom exception, handle it using a try-catch
block.
try {
someObject.someMethod();
} catch (CustomException e) {
// Handle the custom exception
System.out.println("Custom exception occurred: " + e.getMessage());
}
Putting it all together, here's an example demonstrating the creation, throwing, and handling of a custom exception:
// CustomException.java
public class CustomException extends Exception {
public CustomException() {
super("Custom exception message");
}
public CustomException(String message) {
super(message);
}
}
// Example.java
public class Example {
public void someMethod() throws CustomException {
// Simulating a condition that triggers the custom exception
boolean condition = true;
if (condition) {
throw new CustomException("Custom message for the exception");
}
}
}
// Main.java
public class Main {
public static void main(String[] args) {
Example example = new Example();
try {
example.someMethod();
} catch (CustomException e) {
System.out.println("Custom exception occurred: " + e.getMessage());
}
}
}
In this example, we define a custom exception CustomException
and then throw and handle it in the Example
and Main
classes, respectively.
Multitasking in Java:
Thread
class or implementing the Runnable
interface.Multiprocessing in Java:
Multithreading in Java:
Thread
class and the java.util.concurrent
package.Thread
class or implementing the Runnable
interface and then starting these threads using the start()
method.ExecutorService
, ThreadPoolExecutor
, and ConcurrentHashMap
to simplify multithreaded programming and manage thread execution, synchronization, and communication.Here's a simple example demonstrating multithreading in Java:
class MyThread extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000); // Simulate some work
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start(); // Start the first thread
thread2.start(); // Start the second thread
}
}
This example creates two threads (thread1
and thread2
) that execute concurrently, each printing numbers from 0 to 4 with a 1-second delay between each iteration.
In summary:
These concepts are fundamental to understanding how modern computer systems handle concurrent execution and optimize resource utilization.
There are two ways to create threads in JAVA
thread
classrunnable
interface.package.java.lang
public class Thread {
- constructors
- methods
- run()
- start()
- join()
- getName() & setName()
- .
- .
- .
}
thread
classrun
methodClass Test extends Thread
{
@Override
void run() // overriding the run method
{
// thread task
}
psvm()
{
Test t = new Test();
t.run(); // X (crossed out) // Wrong way
t.start();
}
}
Starting the Thread:
start()
method, not the run()
method directly. Invoking the run()
method directly will execute the run()
method in the current thread, without creating a new thread of execution.start()
method on the Test
object.start()
method is called on the Test
object to start the thread, which will execute the run()
method asynchronously in a separate thread of execution.The lifecycle of a thread in Java consists of several states through which a thread transitions during its execution. Here's a short explanation of the lifecycle stages of a thread:
New:
Runnable:
start()
method on a thread object, it enters the "Runnable" state. In this state, the thread is eligible to run, but the scheduler has not yet selected it to run on the CPU.Running:
Blocked/Waiting:
Timed Waiting:
Thread.sleep()
or waiting for the completion of a timed operation.Terminated / Dead State:
run()
method. Once a thread is terminated, it cannot be restarted or run again.Throughout its lifecycle, a thread may transition between these states based on various conditions and events, such as CPU scheduling decisions, I/O operations, synchronization, and signaling between threads. Proper management and understanding of thread lifecycle states are essential for developing concurrent and multithreaded applications in Java.
package.java.lang
public interface Runnable
{
- method
- run()
}
Class Test implements Runnable
{
public void run()
{
// thread task
}
}
psvm()
{
Test t = new Test();
}
implement the Runnable interface
Override the run method
Create an object of user defined class
Create an object of thread class and pass the parameter in the constructor
start the thread
! AI Generated content starts : Fixing the code block above.
To fix the provided code, we need to complete the psvm()
method by creating a Thread
object and starting it to execute the run()
method defined in the Test
class, which implements the Runnable
interface. Here's the corrected version:
class Test implements Runnable {
public void run() {
// Thread task
System.out.println("Thread task is running");
}
public static void main(String[] args) {
// Create an instance of Test
Test t = new Test();
// Create a Thread object and pass the Test instance to its constructor
Thread thread = new Thread(t);
// Start the thread
thread.start();
}
}
In this corrected version:
We have implemented the run()
method in the Test
class to define the task that the thread will execute.
In the main()
method, we create an instance of Test
and a Thread
object, passing the Test
instance to the Thread
constructor.
Finally, we start the thread using the start()
method. This will execute the run()
method of the Test
class concurrently with the main thread, printing "Thread task is running" to the console.
! AI Generated content ends
Using Runnable interface is preferred
Thread
class, it becomes tightly coupled with the threading mechanism, which limits its flexibility. On the other hand, implementing the Runnable
interface allows the class to focus on its primary responsibility while leaving the threading concerns to be handled separately. This promotes cleaner and more modular code.Runnable
, your class is free to extend another class if needed, allowing for more flexible class hierarchies.Seen above already
! AI GENERATED :
Here's an example demonstrating performing a single task from a single thread in Java:
public class SingleThreadExample {
public static void main(String[] args) {
// Create a task to perform
Runnable task = () -> {
// Perform the task
System.out.println("Task is being performed by Thread: " + Thread.currentThread().getName());
};
// Create a thread and execute the task
Thread thread = new Thread(task);
thread.start();
}
}
Explanation:
Runnable
lambda expression.Thread
object and pass our task to its constructor.start()
method. This initiates the execution of the task in a new thread.When you run this code, it will output something like:
Task is being performed by Thread: Thread-0
This indicates that the task is being performed by a single thread (in this case, Thread-0
).
AI
Sure, here's an example demonstrating performing a single task from multiple threads by extending the Thread
class:
public class MultipleThreadsExample extends Thread {
public void run() {
// Perform the task
System.out.println("Task is being performed by Thread: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
// Create multiple threads and execute the task
for (int i = 0; i < 5; i++) {
MultipleThreadsExample thread = new MultipleThreadsExample();
thread.start();
}
}
}
Explanation:
MultipleThreadsExample
that extends the Thread
class.run()
method to define the task that each thread will perform.main
method, we create a loop to create multiple instances of MultipleThreadsExample
and start each thread.When you run this code, you'll see output similar to the following (order may vary):
Task is being performed by Thread: Thread-0
Task is being performed by Thread: Thread-1
Task is being performed by Thread: Thread-2
Task is being performed by Thread: Thread-3
Task is being performed by Thread: Thread-4
Each thread is executing the same task concurrently, as in the previous example. However, extending the Thread
class limits the flexibility of your class and is generally not recommended because it does not follow the principle of favoring composition over inheritance. Using Runnable
is typically a better approach for creating threads in Java.
AI Ends
AI
Performing multiple tasks from a single thread by extending the Thread
class is not a typical practice because a single thread usually handles one task at a time. However, if you still want an example where a single thread performs multiple tasks sequentially, here it is:
public class SingleThreadMultipleTasks extends Thread {
public void run() {
task1();
task2();
task3();
}
private void task1() {
System.out.println("Task 1 is being performed by Thread: " + Thread.currentThread().getName());
}
private void task2() {
System.out.println("Task 2 is being performed by Thread: " + Thread.currentThread().getName());
}
private void task3() {
System.out.println("Task 3 is being performed by Thread: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
// Create a single thread to perform multiple tasks
SingleThreadMultipleTasks thread = new SingleThreadMultipleTasks();
thread.start();
}
}
Explanation:
SingleThreadMultipleTasks
class extends the Thread
class.run()
method, which is overridden from the Thread
class, we call three different private methods (task1()
, task2()
, and task3()
), each representing a separate task.main()
method, we create a single instance of SingleThreadMultipleTasks
and start the thread.When you run this code, you'll see output similar to the following:
Task 1 is being performed by Thread: Thread-0
Task 2 is being performed by Thread: Thread-0
Task 3 is being performed by Thread: Thread-0
Keep in mind that while this example demonstrates executing multiple tasks from a single thread, it's generally more efficient to use multiple threads when dealing with multiple tasks to leverage parallelism and better utilize system resources.
AI Ends
AI
Certainly! Here's an example illustrating performing multiple tasks from multiple threads by extending the Thread
class:
public class MultipleTasksMultipleThreads extends Thread {
private String taskName;
public MultipleTasksMultipleThreads(String taskName) {
this.taskName = taskName;
}
public void run() {
// Perform the respective task based on taskName
if (taskName.equals("Task1")) {
task1();
} else if (taskName.equals("Task2")) {
task2();
} else {
System.out.println("Invalid task name");
}
}
private void task1() {
System.out.println("Task 1 is being performed by Thread: " + Thread.currentThread().getName());
}
private void task2() {
System.out.println("Task 2 is being performed by Thread: " + Thread.currentThread().getName());
}
public static void main(String[] args) {
// Create multiple threads for performing multiple tasks
MultipleTasksMultipleThreads thread1 = new MultipleTasksMultipleThreads("Task1");
MultipleTasksMultipleThreads thread2 = new MultipleTasksMultipleThreads("Task2");
// Start the threads
thread1.start();
thread2.start();
}
}
Explanation:
MultipleTasksMultipleThreads
class extends the Thread
class.taskName
parameter in its constructor to identify which task the thread should perform.run()
method, it invokes the appropriate task method (task1()
or task2()
) based on the provided taskName
.task1()
and task2()
methods contain the implementations of the respective tasks.main()
method, we create multiple instances of MultipleTasksMultipleThreads
, each representing a different task, and start them as separate threads.When you run this code, you'll see output similar to the following:
Task 1 is being performed by Thread: Thread-0
Task 2 is being performed by Thread: Thread-1
Each task is executed by a separate thread concurrently, demonstrating the execution of multiple tasks from multiple threads.
AI Gen
Thread()
Thread(Runnable Target)
Thread(String name)
Thread(ThreadGroup tg, Runnable target)
Thread(ThreadGroup tg, String name)
Thread(ThreadGroup tg, Runnable target, String name)
Thread(ThreadGroup tg, Runnable target, String name, Long stackSize)
Categories :
Class Test
{
psvm() // Main Thread
{
sout("hello");
Thead.currentThread().setName("xyz");
sout(Thread.currentThread().getName());
sout(10/0); // will print an error saying something like "Error in `thread_name`"
}
}
currentThread() and getName()
:CurrentThread()
provides a reference to the current threadThead.CurrentThread().setName("xyz");
By default the name provided will be : DIYclass Test extends Thread {
public void run() {
System.out.println("Thread Task");
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
Test t = new Test();
t.start();
System.out.println(Thread.currentThread().getName());
}
}
main
Thread Task
Thread-0
main
thread and the other will be the thread-0
which we have created using Test t = new Test();
implementing the run
methodisAlive()
:class Test extends Thread {
public void run() {
System.out.println("Thread Task");
System.out.println(Thread.currentThread().getName() + " is alive : " + Thread.currentThread().isAlive());
}
public static void main(String[] args) {
Test t = new Test();
t.start();
System.out.println(Thread.currentThread().getName());
System.out.println("t is alive : " + t.isAlive());
}
}
main
Thread Task
t is alive : true
Thread-0 is alive : true
Thread class naming : getName(), setName()
Daemon Thread runs in the background of another thread, it provides service to the thread.
Class Test extends Thread
{
public void run()
{
// thread basic
}
psvm() // main thread
{
Test t = new Test();
t.setDaemon(true);
t.start();
}
}
Thread Execution Methods :
ms
me values dalenge.Interrupt()
method will only work when the thread is in waiting or sleeping state. If it is not in sleeping / waiting thread then calling Interrupt()
method will perform normal behavior.Interrupt()
method the exception associated with it is the Interrupted Exception
.Class Test extends Thread
{
public void run()
{
try
{
for(int i=1; i<=5; i++)
sout(i);
}
catch(Exception e)
{
sout("Exception")
}
}
psvm()
{
Test t = new Test();
t.start();
}
}