Java (Unit-4)
Java (Unit-4)
A thread in Java is the direction or path that is taken while a program is being executed.
Generally, all the programs have at least one thread, known as the main thread, that is
provided by the JVM or Java Virtual Machine at the starting of the program’s execution.
At this point, when the main thread is provided, the main() method is invoked by the
main thread.
Thread is critical in the program because it enables multiple operations to take place
within a single method. Each thread in the program often has its own program counter,
stack, and local variable.
In this case, a thread is created by a new class that extends the Thread class, creating
an instance of that class. The run() method includes the functionality that is supposed to
be implemented by the Thread.
Output
Here, start() is used to create a new thread and to make it runnable. The new thread
begins inside the void run() method.
This is the easy method to create a thread among the two. In this case, a class iscreated
to implement the runnable interface and then the run() method.
The code for executing the Thread should always be written inside the run() method.
Here's a code to make you understand it.
Output
The start() method is used to call the void run() method. When start() is called, a new
stack is given to the thread, and run() is invoked to introduce a new thread in the
program.
The Life Cycle of a Thread in Java refers to the state transformations of a thread that
begins with its birth and ends with its death. When a thread instance is generated and
executed by calling the start() method of the Thread class, the thread enters the
runnable state. When the sleep() or wait() methods of the Thread class are called, the
thread enters a non-runnable mode.
Thread returns from non-runnable state to runnable state and starts statement
execution. The thread dies when it exits the run() process. In Java, these thread state
transformations are referred to as the Thread life cycle.
1. New
2. Runnable
3. Running
4. Blocked (Non-runnable state)
5. Dead
New State
As we use the Thread class to construct a thread entity, the thread is born and is
defined as being in the New state. That is, when a thread is created, it enters a new
state, but the start() method on the instance has not yet been invoked.
Runnable State
A thread in the runnable state is prepared to execute the code. When a new thread's
start() function is called, it enters a runnable state.
In the runnable environment, the thread is ready for execution and is awaiting the
processor's availability (CPU time). That is, the thread has entered the queue (line) of
threads waiting for execution.
Running State
Running implies that the processor (CPU) has assigned a time slot to the thread for
execution. When a thread from the runnable state is chosen for execution by the thread
scheduler, it joins the running state.
In the running state, the processor allots time to the thread for execution and runs its
run procedure. This is the state in which the thread directly executes its operations.
Only from the runnable state will a thread enter the running state.
Blocked State
When the thread is alive, i.e., the thread class object persists, but it cannot be selected
for execution by the scheduler. It is now inactive.
Dead State
When a thread's run() function ends the execution of sentences, it automatically dies or
enters the dead state. That is, when a thread exits the run() process, it is terminated or
killed. When the stop() function is invoked, a thread will also go dead.
Thread Methods
Thread Priorities
The number of services assigned to a given thread is referred to as its priority. Any
thread generated in the JVM is given a priority. The priority scale runs from 1 to 10.
The main thread's priority is set to 5 by default, and each child thread will have the
same priority as its parent thread. We have the ability to adjust the priority of any thread,
whether it is the main thread or a user-defined thread.
Multithreading in Java
In Java, multithreading is the method of running two or more threads at the same time
to maximize CPU utilization. As a result, it is often referred to as Concurrency in Java.
Each thread runs in parallel with the others.
Users are allowed to perform many Many threads are created from a process through
1. tasks by CPU. which computer power is increased.
Isolation and memory protection Isolation and memory protection does not exist in
7. exist in multitasking. multithreading.
Uncaught exception handler will be used to demonstrate the use of exception with
thread. It is a specific interface provided by Java to handle exception in the thread run
method.
There are two methods to create a thread:
1. Extend the thread Class (java.lang.thread)
2. Implement Runnable Interface (java.lang.thread)
System.out.println("Thread is running");
}}}
Output:
Another thread is not supported
Return type: As seen in syntax itself, it does not return any value.
Exception:
1. IllegalArgumentException is thrown when the parametric value is
negative as it isbounded as discussed between [0 — +999999]
Synchronization in java
Synchronization is the capability to control the access of multiple threads to
any shared resource. In the Multithreading concept, multiple threads try to
access the shared resources at a time to produce inconsistent results. The
synchronization is necessary for reliable communication between threads.
Synchronization helps in preventing thread interference.
Synchronization helps to prevent concurrency problems.
1. Process Synchronization
2. Thread Synchronization
1) Process Synchronization:
The process is nothing but a program under execution. It runs independently isolated from
another process. The resources like memory and CPU time, etc. are allocated to the process by
the operation System.
2) Thread Synchronization:
Thread Synchronization helps only one thread to access the shared resources. It won’t allow the
accessing of shared resources at a time. It can be achieved in the following ways.
Synchronized Method
Synchronized block
Static Synchronization
Package
Package in Java is a mechanism to encapsulate a group of classes, sub packages and
interfaces. Packages are used for:
Note: Sequence of the program must be package then import then class.
Preventing naming conflicts.
For example
there can be two classes with name Employee in two packages,
college.staff.BBA.Employee and college.staff.BCA.Employee
1. import package.*;
2. import package.classname;
3. fully qualified name.
1) Using packagename.*
//save by A.java
package pack;
public class A
{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;
class B
{
public static void main(String args[])
{
A obj = new A();
obj.msg();
}
}
3) Using packagename.classname
//save by A.java
package pack;
{
public class A
{
public void msg(){System.out.println("Hello");
}
}
//save by B.java
package mypack;
import pack.A;
class B{
public static void main(String args[])
{
A obj = new A();
obj.msg();
} }
Example:
//Student.java
package student;
class Student
{
private int rollno;
private String name;
private String address;
public Student(int rno, String sname, String sadd}
{
rollno = rno;
name = sname;
address = sadd;
}
public void show()
{
System.out.println(“Roll No :: ” + rollno);
System.out.println(“Name :: ” + name);
System.out.println(“Address :: ” + address);
}
}
// Test.java
package student;
class Test extends Student
{
protected int marksSubjecti;
protected int marksSubject2;
protected int marksSubject3;
protected int marksSubject4;
public Test(int rno, String sname, String sadd,int mi, int m2, int m3, int m4)
{
super(rno,sname,sadd);
marksSubjecti = mi;
marksSubject2 = m2;
marksSubject3 = m3;
marksSubject4 = m4;
}
public void show()
{
super.show();
System.out.println(“Marks of Subject1 :: ” + marksSubject1);
System.out.println(“Marks of Subject2 :: ” + marksSubject2);
System.out.println(“Marks of Subject3 :: ” + marksSubject3);
System.out.println(“Marks of Subject4 :: ” + marksSubject4);
}
}
//Result.java
package student;
public class Result ex..tends Test
{
private int totalMarks;
private float percentage;
private char grade;
public Result(int rno, String sname, String sadd,int mi, int m2, int m3, int m4)
{
super(rno,sname,sadd,ml,m2,m3,m4);
totalMarks=marksSubject1+marksSubject2+marksSubject3+marksSubject4;
percentage = (totalMarks*100.00F/600.00F);
if (percentage >=50.00F)
grade=’D’;
else
if(percentage >=55.00F && percentage<=60.00F)
grade = ‘C’;
else
if (percentage >=6l.00F && percentage<=70.00F)
grade = ‘B’;
else
if(percentage >=7l.00F && percentage<=75.00F)
grade = ‘A’;
else
if (percentage >=76.00F && percentage<=85.00F)
grade = ‘H’;
else
grade = ‘S’;
}
public void show()
{
super.show();
System.out.println(“Total Marks :: ” + totalMarks);
System.out.println(“Percentage :: ” + percentage);
System.out.println(“Grade :: ” + grade);
}
}
//ImportPackageDemo.java
import student.Result;
public class ImportPackageDemo
{
public static void main(String ar[])
{
Result ob = new Result (1001, “Alice”, “New York”,135,130,132,138);
ob.show ();
}
}
Hiding classes:
When we import a package using asterisk (*),all public classes are imported. However, we may prefer to
“not import” certain classes i.e, we may like to hide these classes from accessing from outside of the
package. Such classes should be declared “not public”.
EX:
package p1;
public class X
{
Body of X
}
class Y
{
Body of Y
}
Now ,consider the following code ,which imports the package p1 that contains classes X and Y:
import p1.*;
X objectX;
Y objectY;