digitization, transformation, binary

All About Class Thread in Java

Concept of Concept switching

Context switching is a term defined for the operating systems when multiple processes share a single processor, the operating system, in order to process another request, must stop the current process and assign it to another process.

It executes a sequence of events called a context switch to transfer control from one process to another. During this process, the operating system has to save a lot of information and need to load a lot of information for the upcoming process.

Context switching involves thousands of machine instructions. During multiple thread execution, context switching is provided by java itself.

The Thread class encapsulates all of the information about a single thread of control running in a Java environment. Thread objects are used to control threads in a multithreaded program.

The execution of Java code is always under the control of a Thread object. The Thread class provides a static method called currentThread() that can be used to get a reference to the Thread object that controls the current thread of execution.

In order for a Thread object to be useful, it must be associated with a method that it is supposed to run.

Java provides two ways of associating a Thread object with a method:
Declare a subclass of Thread that defines a run() method. When such a class is instantiated and the object’s start() method is called, the thread invokes this run() method.

Pass a reference to an object that implements the Runnable interface to a Thread constructor. When the start() method of such a Thread object is called, the thread invokes the run()method of the Runnable object.

After a thread is started, it dies when one of the following things happens:
The run() method called by the Thread returns.An exception is thrown that causes the run() method to be exited.The stop() method of the Thread is called.

Thread in Java

A thread in java is a flow of control within a program. It is similar to process except for multiple threads within the same application share much of the same state. They run in the same address space. It means that threads share instance variables but not local variables.

Java provides two ways of associating a Thread object with a method:

  • Declare a subclass of Thread that defines a run() method. When such a class is instantiated and the object’s start() method is called, the thread invokes this run() method.
  • Pass a reference to an object that implements the Runnable interface to a Thread constructor. When the start() method of such a Thread object is called, the thread invokes the run()method of the Runnable object.

Thread class allows us to run multiple programs at a time. A Thread corresponds to the control of the program. Every Thread has its own priority. Threads with higher priority are executed first than the lower priority Threads. Each thread may or may not be marked as Daemon Thread.
During execution, a Thread creates another child Thread, the child Thread will have the same priority as parent Thread. Similarly, if a Daemon Thread creates a child thread, it will be automatically Daemon Thread. When java virtual machine continues to execute, there is usually a single Thread(on Daemon) which calls the main method of some class. The JVM continues to execute threads until one of the following occurs:

  1. The exit() method of class Runtime has been called and the Security Manager has permitted the exit operation.
  2. All Threads that are not Daemon Threads have died either by run time from the call to the run() method or by performing the stop() method.

If several threads are trying to access the same variable without some kind of coordination, we may get the wrong result. To avoid this a thread can reserve the right to use an object until it is finished it’s a task. A thread if important can raise its priority.

Thread class encapsulates all the information about a single thread of control running on the Java interpreter. To create a thread, we must pass a Runnable object (i. e., an object that implements the Runnable interface by defining a run() method) to the Thread constructor, or we must subclass Thread so that it defines its own run() method.

The run() method of the Thread or of the specified Runnable object is the “body” of the thread. It begins executing when the start() method of the Thread object is called. The thread runs until the run() method returns or until the stop() method of its Thread object is called. The static methods of this class operate on the currently running thread. The instance methods may be called from one thread to operate on a different thread.

start() starts a thread running, stop() stops it by throwing a ThreadDeath error. Suspend() temporarily halts a thread. resume() allows it to resume, sleep() makes the current thread stop for a specified amount of time. yield() makes the current thread give up control to any other threads of equal priority that are waiting to run. join() waits for a thread to die. interrupt() wakes up awaiting or sleeping thread (with an InterruptedException) or sets an “interrupted” flag on a non-sleeping thread.

A thread can test its own “interrupted” flag with interrupted() or can test the flag of another thread with isInterrupted(). The objectWait() method makes the current thread block until the objects notify() method is called by another thread.

After a thread is started, it dies when one of the following things happens:

  • The run() method called by the Thread returns.
  • An exception is thrown that causes the run() method to be exited.
  • The stop() method of the Thread is called.

The Structure of the Thread class is given below:


public class java.lang.Thread extends java.lang.Object implements java.lang.Runnable{
//Member Elements
public final static int MAX_PRIORITY; // Max priority of a Thread is 10
public final static int MIN_PRIORITY; // Min priority of a Thread is 0
public final static int NORM_PRIORITY; // NORM priority of a Thread is 5
//Constructors
public Thread();
//Creates and allocates a new Thread object.This constructor is same as Thread(null,null,gName), where gName
//is newly generated name. This is automatic assignment in the form of "Thread-"+n where n is an integer.
public Thread(Runnable target);
//Creates and allocates a new Thread object.This constructor is same as Thread(null,null,gName), where gName 
//is newly generated name. This is automatic assignment in the form of "Thread-"+n where n is an integer.
//target is the object whose run() method is called.
public Thread(Runnable target,String name);
//Creates and allocates a new Thread object.This constructor has the same effect as Thread(null,target,name). 
//target is the object whose run() method is called. and name is the name of the Thread.
public Thread(String name);
//Creates and allocates a new Thread object whose name is specified in the argument. It is same as 
//Thread(null,null,name).
public Thread(ThraedGroup group,Runnable target);
//Creates and allocates a new Thread object.This constructor has the same functionality as 
//Thread(group,target,gName),where gName is newly generated name. This is automatic assignment in the form 
//of "Thread-"+n where n is an integer. This constructor can throw an SecurityException if the current thread 
//can not create a thread in the specified group.
public Thread(ThraedGroup group,Runnable target,String name);
//Creates and allocates a new Thread object.target is the it's run object and name as name specified in the 
//argument.It belong to the ThreadGroup referred by group.If the group is null,the new process belongs to the 
//same group as the Thread(which is creating the new Thread).If the target argument is not null,the run method 
//of the target is called when this Thread is started.If the target method is null, the Thread which is creating 
//this Thread,its run method gets executed. The priority of the newly created Thread is set equals to the priority
//of the Thread creating the new Thread.setPriority() mthod can be used to change the priority.This constructor
// can throw an SecurityException if the current thread
//can not create a thread in the specified group.
public Thread(ThraedGroup group,String name);
//Creates and allocates a new Thread object.. It has the same effect as Thread(group,null,name).
//This constructor can throw an SecurityException if the current thread 
//can not create a thread in the specified group.
//Methods:
public static int activeCount();
public static int enumerate(Thread toArray[]);
public void checkAccess();
public void destroy();
public static boolean interrupted();
public void run();
public synchronized native void start();
public final void join() throws InterruptedException;
public final synchronized void join(long millis) throws InterruptedException;
public final synchronized void join(long millis,int nanos) throws InterruptedException;
public final void resume();
public final void setDaemon(boolean on);
public final void setName(String name);
//Assigns a name of the thread as name for a thread before the exution of that thread.This enables us to identify 
//the thread with a name.This is //helpful for debugging multithreaded application.
public final void setPriority(int newPriority);
//This method sets the thread's priority value with the argument passed.
public final void stop();
public final synchronized void stop(Throwable obj);
public final void suspend();
public native int countStackFrames();
public static native Thread currentThread();
//It is a static method that returns the Thread object which is the currently running thread.
public static void dumpStack();
public static boolean interrupted();
public static native void sleep(long millis) throws InterruptedException;
public static void sleep(long millis,int nanos) throws InterruptedException;
public static native void yield();
public final String getName();
//This function returns the current String value of the thread's name as set by the method setName()
public final int getPriority();
//Returns the thread's current priority
public final ThreadGroup getThreadGroup();
public final native  boolean isAlive();
public final boolean isDaemon();
//return's true if the thread is a daemon thread, else returns false.
public boolean isInterrupted();
public String toString();
}

The details of the Thread class is given as:

public final static int MAX_PRIORITY;

public final static int MAX_PRIORITY describes the highest priority a thread can have.

public final static int MIN_PRIORITY;

public final static int MIN_PRIORITY describes the lowest priority a thread can have.

public final static int NORM_PRIORITY;

public final static int NORM_PRIORITY describes the default priority assigned to a thread.

public Thread();

public Thread() constructor creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes its own run() method when the Thread
object’s start() method is called. This is not useful unless the object belongs to a subclass of
the Thread class that overrides the run() method.

Calling this constructor is equivalent to:
Thread(null, null, genName) where genName is an automatically generated name of the form “Thread-“+n, where n is an integer incremented each time a Thread object is created.

public Thread(Runnable target);

public Thread(Runnable target) method
This method returns
Parameter

public Thread(Runnable target, String name);

public Thread(Runnable target, String name) method
This method returns
Parameter

public Thread(String name);

public Thread(String name) constructor creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread
object’s start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method.

Calling this constructor is equivalent to:
Thread(null, null, name)

The uniqueness of the specified Thread object’s name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

Parameter
name – The name of this Thread object.

public Thread(ThreadGroup group, Runnable target);

public Thread(ThreadGroup group, Runnable target) constructor creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes the run() method of the specified Runnable object when the Thread object’s start() method is called.

Calling this constructor is equivalent to:

Thread(group, target, genName)

genName is an automatically generated name of the form “Thread-“+n, where n is an integer
that is incremented each time a Thread object is created.
Parameter
group – The ThreadGroup object that this Thread object is to be added to.
target – A reference to an object that implements the Runnable interface.

public Thread(ThreadGroup group, Runnable target, String name);

public Thread(ThreadGroup group, Runnable target, String name) constructor Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes the run() method of the specified
Runnable object when the Thread object’s start() method is called.

The uniqueness of the specified Thread object’s name is not checked, which may be a problem for programs that attempt to identify Thread objects by their names.
Parameter
group – The ThreadGroup object that this Thread object is to be added to.
target -A reference to an object that implements the Runnable interface.
name – The name of this Thread object.

public Thread(ThreadGroup group, String name);

public Thread(ThreadGroup group, String name) constructor creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread
object’s start() method is called. This is not useful unless the object belongs to a subclass of
the Thread class that overrides the run() method. Calling this constructor is equivalent to:

Thread(group, null, name)

The uniqueness of the specified Thread object’s name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

Parameter
group – The ThreadGroup object that this Thread object is to be added to.
name – The name of this Thread object.

public static int activeCount();

public static int activeCount() method returns the number of threads in the ThreadGroup of the currently running thread for which the isAlive() method returns true.
This method returns the current number of threads in the ThreadGroup of the currently running thread.

public static native Thread currentThread();

public static native Thread currentThread() method returns a reference to the Thread object that controls the currently executing thread.
This method returns a reference to the Thread object that controls the currently executing thread.

public static void dumpStack();

public static void dumpStack() method outputs a stack trace of the currently running thread.

public static int enumerate(Thread tarray[]);

public static int enumerate(Thread tarray[]) method stores a reference in the array for each of the Thread objects in the ThreadGroup of the currently running thread for which the isAlive() method returns true.

Calling this method is equivalent to:

currentThread().getThreadGroup().enumerate(tarray);

If the array is not big enough to contain references to all the Thread objects, only as many
references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

This method returns the number of Thread objects stored in the array.
Parameter
tarray -A reference to an array of Thread objects.

public static boolean interrupted();

public static boolean interrupted() method determines whether or not the currently running thread has been interrupted.
This method returns true if the currently running thread has been interrupted; otherwise false.

public static native void sleep(long millis);

public static native void sleep(long millis) method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds has elapsed.

READ  How to Work With Java and Images?

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method
called wait() that is similar to sleep() but causes the currently running thread to temporarily
relinquish its locks.

Parameter
millis – The number of milliseconds that the currently running thread should sleep.

public static void sleep(long millis, int nanos);

public static void sleep(long millis, int nanos) method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds have elapsed.

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method
called wait() that is similar to sleep() but causes the currently running thread to temporarily
relinquish its locks.

Parameter
millis – The number of milliseconds that the currently running thread should sleep.
nanos – An additional number of nanoseconds to sleep.

public static native void yield();

public static native void yield() method causes the currently running thread to yield control of the processor so that another thread can be scheduled.

public void checkAccess();

public void checkAccess() method determines if the currently running thread has permission to modify this Thread object.

public native int countStackFrames();

public native int countStackFrames() method returns the number of pending method invocations on this thread’s stack.
This method returns the number of pending method invocations on this thread’s stack.

public void destroy();

public void destroy() method terminates this thread without any of the usual cleanup (i.e., any locks held by the thread are not released).

This method provides a last-resort way to terminate a thread. While a thread can defeat its stop() method by catching objects thrown from it, there is nothing that a thread can do to stop itself from being destroyed.

public final String getName();

public final String getName() method returns the name of this Thread object.
This method returns the name of this thread.

public final int getPriority();

public final int getPriority() method returns the priority of this Thread object.
This method returns the priority of this thread.

public final ThreadGroup getThreadGroup();

public final ThreadGroup getThreadGroup() method returns a reference to the ThreadGroup that this Thread object belongs to.
This method returns the ThreadGroup of this thread.

public void interrupt();

public void interrupt() method interrupts this Thread object.

public final native boolean isAlive();

public final native boolean isAlive() method determines whether or not this Thread object is alive. A Thread object is alive if it has been started and has not yet died. In other words, it has been scheduled to run before and can still be scheduled to run again. A thread is generally alive after its start() method is called and until its stop() method is called.

This method returns true if this thread is alive; otherwise false.

public final boolean isDaemon();

public final boolean isDaemon() method determines whether or not this thread is a daemon thread, based on the value of the daemon attribute of this Thread object.

This method returns true if the thread is a daemon thread; otherwise false.

public boolean isInterrupted();

public boolean isInterrupted() method determines whether or not this Thread object has been interrupted.
This method returns true if this thread has been interrupted; otherwise false.

public final void join();

public final void join() method allows the thread that calls it to wait for the Thread associated with this method to die. The method returns when the Thread dies. If this thread is already dead, then this method returns immediately.

public final synchronized void join(long millis);

public final synchronized void join(long millis) method causes a thread to wait to die. The method returns when this Thread object dies or after the specified number of milliseconds has elapsed, whichever comes first. However, if the specified number of milliseconds is zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.
Parameter
millis -The maximum number of milliseconds to wait for this thread to die.

public final synchronized void join(long millis, int nanos);

public final synchronized void join(long millis, int nanos) method causes a thread to wait to die. The method returns when this Thread object dies or after the specified amount of time has elapsed, whichever comes first. However, if millis and nanos are zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.
Parameter
millis – The maximum number of milliseconds to wait for this thread to die.
nanos – An additional number of nanoseconds to wait.

public final void resume();

public final void resume() method resumes a suspended thread. The method causes this Thread object to once again be eligible to be run. Calling this method for a thread that is not suspended has no effect.

public void run();

public void run() method causes the thread to invoke a run() method. If this Thread object was created without a specified Runnable object, the Thread object’s own run() method is executed. This behavior is only useful in a subclass of Thread that overrides this run() method, since the run() method of the Thread class does not do anything.

public final void setDaemon(boolean on);

public final void setDaemon(boolean on) method sets the daemon attribute of this Thread object to the given value. This method must be called before the thread is started. If a thread dies and there are no other threads except daemon threads alive, the Java virtual machine stops.
Parameter
on – The new value for this thread’s daemon attribute.

public final void setName(String name);

public final void setName(String name) method sets the name of this Thread object to the given value. The uniqueness of the specified Thread object’s name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

Parameter
name – The new name for this thread.

public final void setPriority(int newPriority);

public final void setPriority(int newPriority) method sets the priority of this Thread to the given value.
Parameter
newPriority – The new priority for this thread.

public synchronized native void start();

public synchronized native void start() method starts this Thread object, allowing it to be scheduled for execution. The top-level code that is executed by the thread is the run() method of the Runnable object specified in the constructor that was used to create this object. If no such object was specified, the top-level code executed by the thread is this object’s run() method.

It is not permitted to start a thread more than once.

public final void stop();

public final void stop() method causes this Thread object to stop executing by throwing a ThreadDeath object. The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw a newly created ThreadDeath object. If this thread was suspended, it is resumed; if it was sleeping, it is awakened. Normally, we should not catch ThreadDeath objects in a try statement. If we need to catch ThreadDeath objects to detect a Thread is about to die, the try statement that catches ThreadDeath objects should rethrow them.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. The uncaughtException() method normally outputs a stack trace. However, uncaughtException() treats a ThreadDeath object as a special case by not outputting a stack trace. When the uncaughtException() method returns, the thread is dead. The thread is never scheduled to run again.

If this Thread object’s stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.

public final synchronized void stop(Throwable o);

public final synchronized void stop(Throwable o) method causes this Thread object to stop executing by throwing the given object. Normally, the stop() method that takes no arguments and throws a ThreadDeath object should be called instead of this method. However, if it is necessary to stop a thread by throwing some other type of object, this method can be used.

The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw the Throwable object o. If this thread was suspended, it is resumed; if it was sleeping, it is awakened.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. If the thrown object is not an instance of the ThreadDeath class, uncaughtException() calls the thrown object’s printStackTrace() method and then the thread dies. The thread is never scheduled to run again.

If this Thread object’s stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.
Parameter
o – The object to be thrown.

public final void suspend();

public final void suspend() method suspends a thread. The method causes this Thread object to temporarily be ineligible to be run. The thread becomes eligible to be run again after its resume() method is called. Calling this method for a thread that is already suspended has no effect.

public String toString();

public String toString() method returns a string representation of this Thread object.
This method returns a string representation of this Thread object.

Apart from these Thread class also has inherited methods from class- Object. They are as follows:

  • clone()
  • finalize()
  • hashCode()
  • notifyAll()
  • wait()
  • wait(long, int)
  • equals(Object)
  • getClass()
  • notify()
  • toString()
  • wait(long)

Read more on Inter thread communication here.

Where to use multiple threads or when to use a single thread?

If our program uses sequential logic, where one operation starts another operation and then must wait for another operation to complete before continuing one thread can implement the entire sequence. Using multi-thread in such cases results in more complex programs with no or slight benefits.

As there is a significant overhead to create and start a thread. If an operation involves only a few primitive statements, it is faster to handle with a single thread.

This is even true when the application is asynchronous. Threads share objects, so they need to use the synchronous mechanism to coordinate thread access and maintain state. The synchronization mechanism adds complexity to code.

Thread Creation Concept

Multithreading corresponds to multiple flows of control. It is a conceptual paradigm where we can divide a program into two or more processes that can run in parallel.Java allows us to have inbuilt processes where more than one process can be executed concurrently within a single program.

Java thread is lightweight, meaning they can run in the same memory space. They can communicate themselves(one object of one thread class can call a method of another thread without any overhead of operating system). Threads can execute independently and simultaneously.

So java handles multiple tasks simultaneously using a multi-threaded way. This feature enables to finish tasks before even beginning another.Java coding is mostly sequential single flow execution(single-threaded programming).

A thread is a single flow of control having a beginning a body and end. A thread executes commands sequentially. The ability to support multi-threads is referred to as concurrency. Since the threads in java are subprograms of the main application and share the same memory space. Even though threads appear to run parallel, it is actually sequential but very fast switching of control between threads.

Execution flow of a thread
Execution flow of a thread
Multi thraed
Multi-thread

Once initiated by the main program, Thread A, Thread B, and Thread C run independently, concurrently and share the system resources.

Java provides two way to create a thread.

  • Subclassing the Thread class. Here we define a class and extend to Thread class, then override the run() method.
  • Implementing the runnable interface. Here we implement the runnable interface and define the run() method.

Sub Classing to the Thread Class:

A new thread is born when we create an instance of the java.lang.Thread class. The thread object represents a real threat in the java interpreter and serves as a handle for controlling and synchronizing its execution.
We can perform the following operations on a thread

  • Start a thread.
  • Stop the thread.
  • Suspend it temporarily

The constructor of the Thread class accepts information about where the thread should begin its execution.
(Read about the Thread class.)
Steps:

  1. We need to declare the class as extending to the Thread class.
  2. Override the run() method in the subclass which is responsible for executing the sequence of code that the thread will execute.
  3. Create a thread object and call the start() method to initiate the thread execution.

Example:


class MyThread extends Thread{
//MyThread is a new Thread which extends to Thread Class. This subclass will contain a method called run().run() 
//contains the actual task what thread should perform.
    private String whichThread;
    private int delay;
    MyThread(String myString,int timeOut)
    {
        whichThread=myString;
        delay=timeOut;
    }
//Main method to construct thread and the only method in which thread's behavior can be written. 
//Here we need to override the run() method.
    public void run()
    {
        try{
            sleep(delay);
        }
    catch(InterruptedException e)
    {
        System.out.println("A thread is interrupted");
    }
    finally{
        System.out.println("Hello "+ whichThread+" slept "+delay);
    }    
    }
}
public class TestThread{
    public static void main(String []args){
      MyThread t1,t2,t3;
//creating the object of the class we created earlier. The state of the threads will be newborn
      t1=new MyThread("Thread 1",10);
      t2=new MyThread("Thread 2",20);
      t3=new MyThread("Thread 3",30);
//start() method to start the threads that will invoke the run() method . This will cause the threads to go to runnable state.Java run time will schedule the threads to run by invoking it's run method.
      t1.start();
      t2.start();
      t3.start();
      try{
          t1.join();
          t2.join();
          t3.join();
      }
      catch(InterruptedException e)
      {
          
      }
     }
}
 

the output of the code:
$javac TestThread.java
$java -Xmx128M -Xms16M TestThread
Hello Thread 1 slept 10
Hello Thread 2 slept 20
Hello Thread 3 slept 30
Another Example:
Once we initiate a thread with new and started them, they are running concurrently on their own. The output is not especially sequential. They just do not follow any specific order. Once the thread has been started, we can not decide in which order they may execute the statements.


class A extends Thread{
public void run()
{
for(int i=1;i<5;i++)
{
System.out.println("From Thread A "+i);
}
System.out.println("Exit from Thread A ");
}
}
class B extends Thread{
public void run()
{
for(int j=1;j<5;j++)
{
System.out.println("From Thread B "+j);
}
System.out.println("Exit from Thread B ");
}
}
class C extends Thread{
public void run()
{
for(int k=1;k<5;k++)
{
System.out.println("From Thread C "+k);
}
System.out.println("Exit from Thread C ");
}
}
public class ThraedTest{
public static void main(String args[])
{
new A().start();
new B().start();
new C().start();
}
}
 

the output of the code:

$javac ThraedTest.java
$java -Xmx128M -Xms16M ThraedTest
From Thread A 1
From Thread A 2
From Thread A 3
From Thread A 4
Exit from Thread A
From Thread B 1
From Thread B 2
From Thread B 3
From Thread B 4
Exit from Thread B
From Thread C 1
From Thread C 2
From Thread C 3
From Thread C 4
Exit from Thread C
$javac ThraedTest.java
$java -Xmx128M -Xms16M ThraedTest
From Thread A 1
From Thread A 2
From Thread B 1
From Thread C 1
From Thread A 3
From Thread A 4
Exit from Thread A
From Thread B 2
From Thread B 3
From Thread B 4
Exit from Thread B
From Thread C 2
From Thread C 3
From Thread C 4
Exit from Thread C

Using Runnable Interface:

Read about the runnable interface:
The second way to create Thread is to make use of the runnable interface. With this approach, we need to implement the runnable interface to the class. The runnable interface is already defined in java.lang package with a single method called- run().

An object that wants to serve as the target of a thread can declare that it has an appropriate executable method by implementing the java.lang.Runnable interface.

This run() method is required for implementing threads in our program. While implementing a new thread, a new object will be instantiated from this runnable interface as the target of our thread, meaning the thread will look for the code for run() method within the object’s class instead of the Thread class.
Steps:

  1. Declare the class as implementing the Runnable interface.
  2. Implement the run() method.
  3. Create a thread by defining an object that is instantiated from this “runnable” class as the target of the thread.
  4. Call the thread’s start() method to run the thread.

Example:


class Pen implements Runnable{
    private int price;
    private String name;
    Pen(int price,String name)
    {
        this.price=price;
        this.name=name;
    }
    public void run()
    {
        try{
            Thread.sleep(price*1000);
            System.out.println("A pen "+name+" price is "+price);
        }
    catch(InterruptedException e)
    {
        System.out.println("Pen thread is interrupted");
    }
       
    }
}
class Pencil implements Runnable{
    private int price;
    private String name;
    Pencil(int price,String name)
    {
        this.price=price;
        this.name=name;
    }
    public void run()
    {
        try{
            Thread.sleep(price*2000);
            System.out.println("A Pencil "+name+" price is "+price);
        }
    catch(InterruptedException e)
    {
        System.out.println("Pencil thread is interrupted");
    }
       
    }
}
public class TestThreadRunnable{
    public static void main(String []args){
      Pen myPen=new Pen(2,"Lammy");
      Thread t1=new Thread(myPen);
      t1.start();
      Pencil myPencil=new Pencil(3,"Nataraj");
      Thread t2=new Thread(myPencil);
      t2.start();
      
      try{
          t1.join();
          t2.join();
          
      }
      catch(InterruptedException e)
      {
          
      }
     }
}
 

the output of the code:
$javac TestThreadRunnable.java
$java -Xmx128M -Xms16M TestThreadRunnable
A pen Lammy price is 2
A Pencil Nataraj price is 3
A class instance with the run() method defined within, must be passed in as argument in creating the thread instance so that when they start() method of this instance is called, java runtime knows which run method to execute. This alternative method of creating a thread is useful when the class defining the run() method needs to be a subclass of another subclass. The class can inherit all the data method of the superclass.
Advantage:

  1. Program with multiple threads will result in better utilization of system resources(CPU).
  2. This feature improves the interactive performance of the graphical application
READ  All About Class BitSet in Java

When to use a subclass of thread and when to use runnable?

The Thread class provides a static method called currentThread() that provides a reference to thread object that controls the current thread of execution.

If we want to do something other tasks along with the target thread, we can subclass the Thread class and define the run() method. Subclassing the thread is convenient when the method we want to run in a separate thread does not need to belong to a particular class.

If a method is a part of a particular class that is a subclass of a class other than Thread, in those cases, we need to tell a thread Object to run code in another object that is not a subclass of the Thread class.

We can accomplish this by passing a reference to an object that implements the Runnable interface to the constructor of the Thread class.

The Runnable interface requires that an object has a public method called run() that takes no argument. When a Runnable object is passed to the constructor of the Thread class, it creates a Thread object that calls the Runnable object’s run() method when the thread is started.


Class AutoColorChange extends java.awt.Canvas implements Runnable{
private Thread myThread;
AutoColorChange()
{
MyThread=new Thread(this);
myThread.start();
.....
.....
.....
}
public void run(){
while(true){
setBackGround(java.awt.Color.red);
repaint();
try{
myThread.sleep(100);
}
catch(InterruptedException e){}
setBackGround(java.awt.Color.blue);
repaint();
try{
myThread.sleep(100);
}
catch(InterruptedException e){}
}
}
}

The constructor here creates a new thread bypassing the current object to the Thread constructor. This instructs the Thread to call run() method in the same class. The constructor starts the new thread by calling the start() method.
The class has an instance variable called myThread that contains a reference to the Thread object, so that we can control the thread.

Note: Thread objects have a parent-child relationship. The very first thread which has been created generally does not have a parent. But once one thread has been created, the same thread object can be used to create several other threads. The new threads are called child threads of the thread object. The new threads i.e the child threads generally do not have any significance when we say they are child threads of main thread objects except setting some initial values.

Life Cycle of Thread

Each Thread is java goes through different states when it is created and when it is dead. Read about Thread creation here. Also, read Thread Class here. In this post, I will try to cover the different Thread states.
Below are the Thread states:

  • Newborn
  • Runnable
  • Running
  • Blocked
  • Dead

Below are the methods that move Threads from one state to another.

  • start()
  • stop()
  • suspend()
  • resume()
  • sleep()
  • yield()

Out of which sleep(), suspend() and wait() are used to block a Thread.

Every thread begins its life by calling a run() method. run() holds the body of the code that holds the code that needs to be executed. It is public. It does not take any arguments. It does not have a return value too. It is not allowed to throw an exception.

Here is the pictorial diagram of the Thread life cycle:

life cycle of thread diagram
the life cycle of thread diagram

Newborn: When a Thread is just created by the new statement but not yet run. It is in the newborn state. In this case, the local data members are allocated and initialized. The newborn Thread is not scheduled for running. At this stage we can do two things:

  1. Schedule it for running using start() method
  2. kill it by using kill() method.

Once scheduled, it moves to the runnable state. Any other attempts to move to another state will be thrown as an Exception.

Thread state change
Thread state change

Runnable: The Thread is already ready to run and is waiting for the control of the processor. The Thread may be in the queue and waiting for their turn to be executed. If all the Threads have equal priority, then they are given time slots for execution in round-robin fashion. i.e first come first serve basis.

The Thread that relinquishes control joins the queue at the end and again waits for its turn. The process of assigning time to Threads is known as time slicing. However, if we want a Thread to relinquish control to another Thread equal priority before it turns to come, we need to use the yield() method.

Yield method on thread
Yield method on the thread

Running: The Thread has the control of the processor. Its code is currently being executed. The thread will continue in this state until it gets preempted by a higher priority Thread or until it relinquishes control. A running Thread may relinquish its control in the following situation:

  1. It has been suspended using suspend() method. A suspended Thread can be revived by using a resume() method. This is useful when we want to suspend a Thread for some reason due to certain reasons, but we do not want to kill it.
  2. If the Thread has been made to sleep using the sleep(timeout) method. This signifies that the Thread is out of the queue for this timeout period. The Thread will reenter into the runnable state as soon as the timeout period elapsed.
  3. If the Thread has been told to wait until some event occurs. This is done using the wait() method. The Thread can be rescheduled to run again using the notify() method.
interruption in thread execution
interruption in thread execution

Blocked: A Thread is blocked when it is prevented from the Runnable or running state and is waiting for some event in order to reenter the scheduling queue. This happens when the Thread is suspended, sleeping or waiting in order to satisfy certain requirements. A blocked thread is considered “not runnable” but not dead and therefore fully qualified to run again.

Dead: The Thread has finished it’s the execution of its run() method or stopped by another Thread. When it completes its execution of a run() method, it is said to be a natural death. When we kill a Thread by sending a stop() method, this is considered a premature death. A Thread can be killed as soon as it is born or while running or in not runnable condition.

in summary, a thread dies when one of the following happens:

  • The run() method called by the Thread returns.
  • An exception is thrown that causes the run() method to be exited.
  • A stop() method of the thread is called.

The methods to change the Thread status:

start():

A newborn state can only start if the start() method is called. Once start() is called a thread proceeds to execute the run() method of its target object.

A newborn Thread with this method enters into runnable state and java runtime creates a system Thread context and starts its execution. This method for a Thread object can be called once only.

When the start() method is called the Thread object becomes associated with a scheduled thread in the underlying environment. The thread is now scheduled to run until it dies unless it is suspended or go to an unrunnable state.

class MyClass implements Runnable{
...
...
public void run()
{
while(true){
//do something
doSomething();
}
}

To use it, we create a Thread object with an instance of MyClass as its target object and invoke its start() method.

MyClass mc=new MyClass("Hello");
Thread mt=new Thread(mc);
mt.start();

This can be achieved by putting these code in MyClass’s constructor

class MyClass implements Runnable{
Thread mt;
MyClass(String str){
mt=new Thread(this);
mt.start();
}

The argument we pass to Thread constructor is this-  the current object instance. mt is the thread reference that is kept inside the instance variable to stop or do some other operation.

The Thread class itself implements the Runnable interface and it has its own run() method which we can override.

class MyClass extends Thread{
....
public void run(){
while(true){
//do something
doSomething();
}
}

If we create a thread in this way, the default or empty constructor of the Thread class makes itself the default target. By default, the thread executes its own run() method when we call start().

The subclass of Thread must override the run() method of the Thread class as Thread class defines an empty run() method.

To start the thread we will create the instance of MyClass.

MyClass mc=new MyClass("Hi");
mc.start();

Alternatively, we could have started by calling start in the argument constructor itself.

class MyClass extends Thread{
MyClass(String str)
{
start();
}
...
}

Here the MYClass object just calls its start() method when it is created.

stop():

This method is responsible to stop a Thread immediately. This is often an abrupt way to stop a Thread. This moves the state of the current Thread to Dead state. A Thread will also move to the dead state automatically when it reaches the end of its method.

The stop() method may be used when the premature death of a Thread is required. The stop() method of the class Thread works by throwing a ThreadDeath object in the run method of a Thread.

stop(throwable) is also available that takes Throwable as an argument and throws that exception.

mt.stop(new MyCancelWorkException());

mt is the working thread.

Normally we should not catch a ThreadDeath object using a try statement. If we need to catch ThreadDeath object in a try statement just to detect if a thread is about to die, then the ThreadDeath object needs to be rethrown.

In case, when an object ThreadDeath of similar is thrown out of the run() method for the Thread, then the uncaughtException() method of the ThreadGroup for the Thread is actually called. If the thrown object is an object of the ThreadDeath class, the thread just dies and the thrown object is ignored.

Otherwise, if the thrown object is of any other class, uncaughtException() calls the thrown object’s printStackTrace() method. The thread dies and the object thrown is ignored.

In all the cases, if there are any nondaemon threads running in the system, the current program continue executing in the system.

isAlive():

Before start() method,isAlive() method always returns false.However after start() method isAlive() returns true. This is used to check the state of the thread.

It is possible for isAlive() method to return true before start() returns but not before start() method is called.This can happen because the start() method can return either before the started thread begins to run or after it begins to run. The method that called start() and the new thread are now running concurrently. On a multiprocessor environment, the start() method can even return at the same time the started Thread begins to run.

Thread objects have a parent-child relationship. However, the first thread created in a java environment does not have a parent thread. After the first Tread object is created, the thread object that controls the thread used to create another thread Object is considered to be the parent of the newly created thread.

This parent-child relationship is used to supply some default values when a Thread object is created but has no further significance once a Thread has been created.

suspend(): It temporary stops a thread and later can start the Thread again.

resume(): This method is received by a suspended Thread. There is no guarantee that the suspended Thread will run immediately as there may be high priority Thread running already or waiting. However, this method will make a suspended Thread runnable.

Note- suspend and resume can be used in the situation where thread’s setup is very expensive.

sleep(int n): This method asks java runtime to put current Thread to sleep for n milliseconds. After n milliseconds the Thread will eligible to run again. Thread.sleep is a static method of the Thread class that puts the currently executing thread to delay for a specified time. Thread.sleep() method throws an InterruptedException if it is interrupted by another thread.

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

Yield():

When the thread completes its execution and it has nothing to perform, the thread calls Yield() method of its Thread object.

The yield() method causes the runtime to switch the context from the current Thread to the next available and runnable Thread. This is one way to ensure that the Threads at lower priority do not get started or ignored. So when a thread has nothing to do further, it can call the yield() method of its Thread object. This method tells the scheduler to run a different thread.

The value of calling yield() method depends heavily on whether the scheduling mechanism of the platform on which the code is running is preemptive or non-preemptive.

Preemptive scheduling

A preemptive scheduling mechanism guarantees that no single thread uses more than its fair share of the processor. If a thread runs for that amount of time without yielding control to another thread, the scheduler preempts the thread and causes it to stop running so that another thread can run.

non-preemptive scheduling

A non-preemptive scheduling mechanism can not preempt threads. A non-preemptive scheduler relies on the individual threads to yield control of the processor frequently so that it can provide reasonable performance.

A thread explicitly yields control by calling the thread object’s yield() method. More often, however, a thread implicitly yields control when it is forced to wait for something to happen elsewhere.

Calling a Thread objects yield() method during a lengthy computation can be quite valuable on a platform that uses a non-preemptive scheduling mechanism as it allows other threads to run. Otherwise, the lengthy computation can prevent other threads from running.

On a platform that uses a preemptive scheduling mechanism, calling yield() does not usually make any noticeable difference in the responsiveness of threads.

Once the yield() method has been called, we can tell when the thread will be scheduled to run again. If we want to prevent a thread from being scheduled to run until a specified amount of time has elapsed, we need to use the sleep() method.

Interrupting a thread

As I said earlier, sleep(), suspend() and wait() are used to block a Thread. A Thread can be temporarily suspended or blocked from entering into runnable and subsequently running state by using either of the following Thread methods:

  • sleep(int n):  blocked for a specific time n
  • suspend(): blocked until further order.
  • wait(): block until a certain condition occurs
  • join(): One thread waits for another thread to complete its execution
  • interrupt(): responsible for interruption of thread execution.

These methods cause the Thread to go into a blocked(or not runnable) state. The Thread will return to runnable state when the specified time is elapsed in case of sleep(), the resume() method is invoked in case of suspend() and notify() method is called in case of wait().

These methods(wait(),join()) are designed to throw an InterruptedException. These methods temporarily suspend the execution of a thread. If a thread is waiting for one of these methods to return and another thread calls interrupt() on the waiting thread, the method that is waiting for throws an InterruptedException.

The interrupt() method sets an internal flag in a Thread object.Before the interrupt() method is called,the isInterrupted() method of the thread object always returns false. After the interrupted() method is called,isInterrupted() returns true.

If we need to kill a thread in a way that allows it to complete what it is currently doing before dying(like if the thread is middle of processing something), thread class provides an interrupt() method.

In summary:

A thread continues to execute until one of the following things occurs:

  • It returns from its target run() method which is completed the task it was supposed to do.
  • It is interrupted by an uncaught exception
  • Its stop() method is called.

So if so happen that run() method for a thread never ends or the stop() method is never called, in those scenarios that particular thread lives on even after the application that created the threads was killed. In this scenario, these threads being application threads keep consuming and occupying resources.

If we want to create some background threads to do some tasks, we can use the setDaemon() method to mark a thread as a daemon thread that should be killed and discarded when no other application thread remains.

READ  What is Cucumber and How to Work With Cucumber?

So java interpreter continues to run until all threads have completed. But when daemon threads are only available, the interpreter will exit. We do not need to kill the daemon threads. Java automatically kills them all.

Inter Thread Communication:

Before you start reading  this post please read this post for thread creation concept,read this post for actual thread class and read this life cycle of a thread. These links will give you a better idea how a thread works. Coming back to the topic,Inter thread communication happens in three ways.

  • Through common shared data
  • Using thread control methods
  • Through inter process communication

Through common shared data
All the threads in the same program share the same memory space.If an object is accessible to various thread then these threads share access to that object’s data members and thus communicate with each other.
Using thread control methods
There are three ways by which threads communicate to each other by this technique.
They are as follows:

  1. suspend();–> A thread can suspend itself and waits for another thread to resume it.
  2. resume();–>A thread can wake another thread (waiting state) through resume method. Then they can run concurrently.
  3. join()–>This method is used for caller thread to wait for completion of the called thread.

Through inter process communication
There are three methods available for inter process communication in this technique. They are as follows:

  1. wait();–>This method tells the caller thread to give up the monitor and make the calling thread wait until either time out occurs or another thread calls the same threads notify() or notifyAll() method.
  2. notify();–>This method wakes up the only one(first) waiting thread called wait() or the same object
  3. notifyAll();–>This method will wake up all the threads that have been called by wait() on the same object.

These three methods are defined in class -Object under java.lang package. These three methods provide an elegant interprocess communication mechanism to take care of a deadlock situation in java.
A deadlock may occur when a thread holding the key of the monitor is suspended or is kept waiting for another thread’s completion. If the other thread is waiting or needs to get into the same monitor, both threads will be waiting forever.

Deadlock,Synchronized and Thread Controlling in java:

Java can execute Threads in the same memory space,hence it is easy to communicate between two or more threads. Inter thread communications allow threads to each other or wait.Since they are running in the same memory space it is also possible to access the same resources(variables,methods etc) in an object at the same time.

DeadLock:

When two or more threads are waiting to gain control of a resource.(refer here for more details).They want to access the data concurrently.Due to some reason,the condition on which the waiting threads rely on to gain control does not happen,it cause a condition called Deadlock.Assume that the threadA must access method1 before it releases method2 but theadB can not release method1 until it get hold of method2. As because they are mutually exclusive,a deadlock will occur.
It may so also happen that thread1 did not finish writing to a resource before that another thread thread2 is trying to read the same.So thread1 does not leave the control where as thread2 needs the control to read it.

Synchronization:

Idea of Mutex or monitor:

When we declare a method as synchronized,java creates a “monitor” and hands it over the thread that calls the method first time.A monitor is an object which is used as a mutually exclusive lock called mutex. So only one thread can own a monitor at a given point of time.When a thread acquires a lock it is said to have entered the monitor.As long as the thread holds the monitor,no other thread can enter the synchronized section of the code.A monitor is like a key and the thread that holds the key can only open the lock.All other threads trying to enter into the monitor will be suspended until the owner of the monitor exits the monitor.

Implementation of Mutex or monitor:

In java there is nothing called mutex or monitor as such. It is a concept and all java objects have their own implicit monitor associated with them. The keyword Synchronized is used by which method(s)
or block of code or block of statements can be made to protect from simultaneous access.When a class is designed with threads in mind,the class designer decides which methods should not be allowed to execute concurrently.When a class with synchronized method is instantiated , the new object is given its own implicit monitor.The entire duration a thread is a synchronized method,all other threads those try to call any other synchronized method on the same instance would have to wait.In order to exit from the monitor and relinquish the control of the object to next waiting thread, the owner of the monitor needs to return from the method.

We can have a block of code,method marked as synchronized:


synchronized(lock-object)
{
//synchronized code block
}
or
synchronized method1(){
//body of the synchronized method
}
synchronized method2(){
//body of the synchronized method
}
 

When a thread has completed its work of using synchronized method or block of code,it will hand over the monitor to the next thread that is ready to use the same resource.
If we create same priority thread, we can not control the execution of them.


class Thread1 extends Thread{
    public void run(){
        System.out.println("Thraed1 is running");
        try{
            System.out.println("Thraed1 is going to sleep");
            sleep(10000);
            System.out.println("Thraed1 is finished its execution");
        }
        catch(Exception e)
        {
            System.out.println("Some Exception is occured in Thread1");
        }
    }
}
class Thread2 extends Thread{
    public void run(){
        System.out.println("Thraed2 is running");
        System.out.println("Thraed2 is suspended");
        suspend();
        System.out.println("Thraed2 is running again");
    }
}
public class ControlMyThread{
    public static void main(String args[])
    {
        Thread1 th1=new Thread1();
        Thread2 th2=new Thread2();
        th1.start();
        th2.start();
        try{
            System.out.println("Resume Thraed2");
            th2.resume();
            System.out.println("lets wait for 10 seconds");
            th2.sleep(10000);
            System.out.println("Thraed2 is ready for stop");
        }
        catch(Exception e)
        {
            System.out.println("Some Exception is occured ");
        }
    }
}
 

The output for the first time:
$javac ControlMyThread.java
Note: ControlMyThread.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
$java -Xmx128M -Xms16M ControlMyThread
Resume Thraed2
Thraed2 is running
Thraed2 is suspended
Thraed1 is running
lets wait for 10 seconds
Thraed1 is going to sleep

2nd time output:
$javac ControlMyThread.java
Note: ControlMyThread.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
$java -Xmx128M -Xms16M ControlMyThread
Resume Thraed2
Thraed2 is running
Thraed2 is suspended
Thraed1 is running
Thraed1 is going to sleep
lets wait for 10 seconds

However we can control the priority of the thread by using a properties called Thread_Priority. I have written a separate post here to discuss more about controlling of thread using priority.

Controlling of thread

The methods that helps us to control the thread are:

  • start()
  • isAlive()
  • stop()
  • wait()
  • join()
  • interrupt()

Thread Priority Concept Simplified in Java:

In my earlier post here I have shown details about a thread and how to create a thread. In this post, we will see an important property of a thread called Priority. In java, each thread is assigned a priority which affects the execution of the thread. By default, threads will be created with normal priority and threads with having same priority are given equal time slot to execute. Mostly it is a first come first serve basis.
Whenever multiple threads are ready for execution, the java will choose the highest priority thread and will execute. For a lower priority thread to gain control, one of the following condition should happen to a high priority thread:

  1. It stops running at the end of the run().
  2. It is made to sleep using sleep()
  3. It is made to wait using wait().

If another thread of a higher priority comes along the currently running thread will be preempted by the incoming thread along, forcing the current thread to move to runnable state. Higher priority threads will always preempt any lower priority thread.
Also, read here controlling deadlock and synchronization.

Although java does not guarantee much about how threads are scheduled it does guarantee that a thread with a priority higher than that of another thread will be scheduled first to run than the lower priority thread.

The priority of a thread is set when the Thread object is created by passing an integer to the constructor.
if an explicit priority is not set or specified, the Thread inherits the parent’s priority.
Before setting the priority of a Thread object, the setPriority() method checks the maximum allowable priority for the ThreadGroup that contains the Thread. It is done by calling the getMaxPriority() method on the ThreadGroup.

If the call to setPriority() tries to set the priority to a value that is higher than the maximum allowable priority for the ThreadGroup, the priority is set to the maximum priority the same as the ThreadGroup.
It is possible for the current priority of a Thread to be greater than the maximum allowable priority of the ThreadGroup. In that case, an attempt to raise the priority of the Thread results in its priority being lowered to the maximum priority.

How to set priority to a thread:


ThreadName.setPriority(int priorityNumber);

int priorityNumber is a constant ranging from 0 to 10. Most user-level processes should be NORM_PRIORITY+/- 1
An example:


class A extends Thread{
    public void run(){
        System.out.println("Running Thread A");
        for(int i=0;i<10;i++){
          System.out.println("Running from Thread A "+i);   
        }
         System.out.println("Ending Thread A");
    }
}
class B extends Thread{
    public void run(){
        System.out.println("Running Thread B");
        for(int i=0;i<10;i++){
          System.out.println("Running from Thread B "+i);   
        }
         System.out.println("Ending Thread B");
    }
}
class C extends Thread{
    public void run(){
        System.out.println("Running Thread C");
        for(int i=0;i<10;i++){
          System.out.println("Running from Thread C "+i);   
        }
         System.out.println("Ending Thread C");
    }
}
public class ThreadPriorityTest{
    public  static void main(String args[])
    {
        A threadA=new A();
        B threadB=new B();
        C threadC=new C();
        threadC.setPriority(Thread.MAX_PRIORITY);
        threadB.setPriority(threadA.getPriority()+2);
        threadA.setPriority(Thread.MIN_PRIORITY);
        System.out.println("Start thraed A");
        threadA.start();
        System.out.println("Start thraed B");
        threadB.start();
        System.out.println("Start thraed C");
        threadC.start();
        System.out.println("Out of main thread");
    }
}

output of the code:
$javac ThreadPriorityTest.java
$java -Xmx128M -Xms16M ThreadPriorityTest
Start thraed A
Start thraed B
Running Thread A
Start thraed C
Running from Thread A 0
Running from Thread A 1
Running from Thread A 2
Running from Thread A 3
Running Thread B
Out of main thread
Running from Thread A 4
Running from Thread B 0
Running from Thread B 1
Running Thread C
Running from Thread A 5
Running from Thread C 0
Running from Thread B 2
Running from Thread B 3
Running from Thread B 4
Running from Thread B 5
Running from Thread B 6
Running from Thread B 7
Running from Thread B 8
Running from Thread B 9
Ending Thread B
Running from Thread C 1
Running from Thread C 2
Running from Thread C 3
Running from Thread C 4
Running from Thread C 5
Running from Thread C 6
Running from Thread C 7
Running from Thread C 8
Running from Thread C 9
Ending Thread C
Running from Thread A 6
Running from Thread A 7
Running from Thread A 8
Running from Thread A 9
Ending Thread A

Another Example:


class clock implements Runnable{
    int tick=0;
    Thread t;
    private boolean isRunning=true;
    public clock(int priority)
    {
        t=new Thread(this);
        t.setPriority(priority);
    }
    public void run()
    {
        while(isRunning){
            tick++;
        }
    }
    public void stop()
    {
        isRunning=false;
    }
    public void start()
    {
        t.start();
    }
    public void join(){}
}
public class MyClockTest{
public static void main(String []args){
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    //main thread is given highest priority
    clock bigHand=new clock(Thread.NORM_PRIORITY+2);
    clock smallHand=new clock(Thread.NORM_PRIORITY-2);
    //two thread are initialized with different priorities
    bigHand.t.setName("BigHand");
    smallHand.t.setName("SmallHand");
    smallHand.start();
    bigHand.start();
    //all three threads are running
    try{
        Thread.sleep(1000);
        //block the main thread 1 second
    }
    catch(Exception e){}
    smallHand.stop();
    if(bigHand.t.isAlive())
    {
         System.out.println(bigHand.t.getName()+"is running");
    }
     if(smallHand.t.isAlive())
    {
         System.out.println(smallHand.t.getName()+"is running");
    }
    bigHand.stop();
    try{
        bigHand.join();
        smallHand.join();
    }
    catch(Exception e){}

    System.out.println(smallHand.t.getName()+"is running for "+smallHand.tick);
    System.out.println(bigHand.t.getName()+"is running for "+bigHand.tick);

     }    
}

output of the code:
$javac MyClockTest.java
$java -Xmx128M -Xms16M MyClockTest
BigHandis running
SmallHandis running
SmallHandis running for 411997559
BigHandis running for 412531380

Daemon Thread Concept

What is a daemon thread?

Daemon threads are service threads. They keep on running to perform a service. Their main objective is to provide different services to other threads. They normally run in an infinite loop and attain client thread’s requesting service when no other thread is present or exists. The Daemon thread automatically exists.

It works without having any connection with the overall state of the program, like Garbage collector or a thread that traps the mouse events
The application threads are not daemon threads but the system threads are daemon threads.

If a thread dies and there are no other threads to run, daemon threads remain alive until java virtual machine stops. JVM does not wait for the death or destruction of Daemon thread before concluding a program.

If a daemon attribute is not explicitly specified, the Thread inherits the daemon attribute of its parent thread.

A Thread object has a boolean attribute which can specify if the thread is a daemon or not. While creating a daemon thread if no attribute is explicitly set, the Thread inherits the daemon attribute of its parent Thread object.

Here is the code to create a Daemon thread


Thread t=new Thread();
//creates a new thread
t.setDaemon(true);
//mark the thread as daemon thread

Methods of Daemon thread

By default, all threads created by Daemon threads are also Daemon threads.
Below are the methods supported by a Daemon thread:

Method Name Returns Description Comments
getName() String returns the name of the ThreadGroup
setName() void Sets the name of the ThreadGroup
getParent() ThreadGroup returns the parent ThreadGroup of the thread or ThreadGroup
getMaxPriority() int Returns the maximum priority of the ThreadGroup
activeCount() int Returns the active thread of a ThreadGroup
activeGroupCount() int Returns the number of active ThreadGroups in the ThreadGroup
isDaemon() boolean Returns true if the thread is a daemon thread else returns false
setDaemon() void Sets the thread as a daemon thread

Class IllegalThreadStateException in Java

IllegalThreadStateException is thrown from code to indicate that the thread is not in an appropriate state for the required or requested operation. The call to sleep() method is enclosed with a try block followed by a catch block. The sleep() method may throw an exception, which needs to be caught and handle.
Java throws IllegalThreadStateException whenever we attempt to invoke a method that a thread can not handle in the given state.

Example-

A sleeping thread can not deal with the resume() method as a sleeping thread can not receive any messages or instructions. It is even true with the suspend() method when it is used on a blocked(Not runnable) thread.

or The thread maybe already started and running when we want to start the same thread.

The structure of the class IllegalThreadStateException is as follows:

public class java.lang.IllegalThreadStateException extends java.lang.IllegalArgumentException{
//constructor
public IllegalThreadStateException();
//constructs an empty IllegalThreadStateException object that is an object with no message specified.
public IllegalThreadStateException(String message);
//constructs an IllegalThreadStateException object with the message specified.
}

The class IllegalThreadStateException also inherits methods from class Object and Throwable.

From Object class From Throwable class
clone() fillInStackTrace()
getClass() getMessage()
notify() printStackTrace()
wait() printStackTrace(PrintWriter)
wait(long, int) getLocalizedMessage()
wait(long) printStackTrace(PrintStream)
equals(Object)
toString()
finalize()
hashCode()
notifyAll()

Class ThreadDeath error in Java

ThreadDeath error instance is thrown from an application when the stop() method with zero arguments is called for a thread. It is used to kill the thread. The victim thread throws this error to indicate that it has been killed without providing any reason. It also indicates that the victim thread should terminate.

This is a very unusual way to terminate a thread without printing any error message or giving justification to the interpreter to exit. This type of Error should not be caught. If we catch this type of Error to do some cleanup activity for the thread, we must re-throw the Error to terminate the thread.

Normally we should not catch ThreadDeath object is a try statement. If at all, we need to catch the ThreadDeath objects to detect that a Thread is about to die, the try statement that catches the ThreadDeath objects should rethrow then.

When an object (ThreadDeath or otherwise) is thrown out of a run() method for the thread, the uncaughtException() method of the ThreadGroup for that thread is called.

If the thrown object is an instance of the ThreadDeath class, the thread dies and the thrown object is ignored.

Otherwise, if the thrown object is of any other class, UncaughtException() calls the thrown object’s printStackTrace() method, the thread dies and the thrown object is ignored.

In both cases, if there are other nondaemon threads running in the system, the current program continues to run.

The class structure of ThreadDeath is given as:

public class java.lang.ThreadDeath extends java.lang.Error{
//constructor
public ThreadDeath();
//constructs an empty ThreadDeath object that is an object with no message specified.
} 

The class ThreadDeath error also inherits methods from class Object and Throwable.

From Object class From Throwable class
clone() fillInStackTrace()
getClass() getMessage()
notify() printStackTrace()
wait() printStackTrace(PrintWriter)
wait(long, int) getLocalizedMessage()
wait(long) printStackTrace(PrintStream)
equals(Object)
toString()
finalize()
hashCode()
notifyAll()

LEAVE A REPLY

Please enter your comment!
Please enter your name here