Java/Java Thread and Multithreading

From Meshplex

Jump to: navigation, search
Image:Java_programming.jpg
Introduction to Java
Overview of Java
How to Setup Java on your PC
Data Types, Variables,and Arrays
Operators
Packages, Classes, and Interfaces
Java Program
Modifiers
Control Statements
Exception Handling
Object Oriented Programming
Wrappers
Strings
Math
Arrays
Random Numbers
Date and Time
Regular Expressions
Java Collections
Generics
Java Thread and Multithreading
Java IO and file Handling
Java Network Programming
RMI
Image, Audio, Video
GUI
Applets
Internationalization
JDBC
Java and XML

Java provides the facility of multi threaded programming which means that java enables the feature in which two or more parts of a program can run simultaneously without conflicting with each other and each part of the program is called “thread”. This multi threaded program is a very good example of multi tasking. It helps us to write programs that make the maximum use of CPU time as we keep the CPU busy with various simultaneously running tasks hence providing minimum idle time for the CPU.

Threads exist in several states. A thread can be running. It can be ready to run as soon as it gets that CPU is available.. A running thread can be suspended, which temporarily suspends its activity. A suspended thread can then be resumed, allowing it to pick up where it left off. A thread can be blocked when waiting for a resource. At any time, a thread can be terminated, which halts its execution immediately. Once terminated, a thread cannot be resumed.

Thread Priorities

Java provides the priority in the form of integer value to each of its thread which decides how that particular thread will be treated in comparison to the other threads which are running. This priority doesn’t really work if there’s only single thread which is running. Ideally it is said that the higher priority threads more CPU time but practically the scenario is not like this as the CPU time depends on various other factors too apart from the thread priority. This switching from execution of one thread to another on the basis of its priority value is called “Context Switch”.

The basic rules for context switch are as under:

■ A thread can voluntarily relinquish control. In this scenario, all other threads are examined, and the highest-priority thread that is ready to run is given the CPU.

■ A thread can be preempted by a higher-priority thread. In this case, a lower-priority thread that does not yield the processor is simply preempted—no matter what it is doing—by a higher-priority thread. Basically, as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking.

Since java is designed to work in various environments it is very important that the threads which have same level of priority should be controlled once in a while.

To set a thread’s priority, use the setPriority( ) method, which is a member method of Thread.

General syntax of thread priority is final void setPriority ( Int level)

Level is the new priority setting for the particular calling thread and this value may range from the MIN_PRIORITY and MAX_PRIORITY.

We can always find out the current priority setting by calling the getPriority( ) method of the thread by writing this line of code final int getPriority( )

Messaging: Java provides the feature to the threads to communicate with each other with the help of predefined methods which are available with all the objects. It allows a thread to enter a synchronised method on an object and then wait till the other thread communicates it to come out of that .

Main Thread: In the Java programming whenever we start a program the first thread which starts its execution first is called the “main thread” of the program. It is a very important thread as it will lead to have other “child” thread running in the program and most of the times it also becomes the last thread to finish the execution of shutdown operations.

The main thread although is created automatically with the starting of the program it can be controlled like other thread by getting the reference of the thread by calling currentThread( ) method.

Creating a Thread

Java provides two ways of creating the thread:

■ we can implement the Runnable interface.

■ We can also extend the Thread class, itself.

Let’s have a look at each one of them .

Runnable Interface

We can create a thread on any object that implements Runnable. To implement Runnable, a class need only implement a single method called run( ), which is declared as under:

public void run( )

Inside run( ), the code is defined that constitutes the new thread. After the class is created that implements Runnable, an object is instantiated of type Thread from within that class.

public class RunnableExample implements Runnable {
 
  private String threadName;
 
  public RunnableExample(String name) {
    threadName = name;
  }
 
  public void run() {
 
    for(int i = 0; i < 1000; i++) {
     System.out.println("Thread " + threadName + " : " + i); 
    }
  }
 
  public static void main(String args[]) {
    Thread thread1 = new Thread(new RunnableExample("A"));
    thread1.start();
    Thread thread2 = new Thread(new RunnableExample("B"));
    thread2.start();    
  }
}

Try the above code. You will find some interesting results every time you execute the code. You can see that we have used start() method. Main purpose of start method is to start the thread. It asks JVM to allocate space and time for the thread so that the thread can execute.

Extending Thread

Another way of creating the thread is to create a new class which will extend the thread. And later we will create the instance of it. The class which is been extended should override the run ( ) method and should also call start ( ) method to start the execution of the newly made thread.

public class ThreadExample extends Thread {
 
  private String threadName;
 
  public ThreadExample(String name) {
    threadName = name;
  }
 
  public void run() {
 
    for(int i = 0; i < 1000; i++) {
     System.out.println("Thread " + threadName + " : " + i); 
    }
  }
 
  public static void main(String args[]) {
    Thread thread = new ThreadExample("A");
    thread.start();    
  }
}
Creating multiple Threads

It is also possible to have multiple threads which will run simultaneously.

This will be illustrated to you with an example:

public class ThreadExample extends Thread {
 
  private String threadName;
 
  public ThreadExample(String name) {
    threadName = name;
  }
 
  public void run() {
 
    for(int i = 0; i < 1000; i++) {
     System.out.println("Thread " + threadName + " : " + i); 
    }
  }
 
  public static void main(String args[]) {
    Thread thread1 = new ThreadExample("A");
    thread1.start();
    Thread thread2 = new ThreadExample("B");
    thread2.start();    
  }
}

Using isAlive( ) and join( )

As we have discussed earlier in the heading Main thread that normally it is recommended that the main thread which starts firstly when the program is started should ideally end also in the last thus making sure that all the other child threads have finished their execution before the main thread has ended its execution and this is made possible normally with the sleep( ) function within main( ) but this is not the ideal solution .

Java provides us with a better solution in threads by which we can find out whether all other child threads have finished executing before the main thread and it is done in two ways as mentioned:

1. we can call the isAlive( ) method which will return the value as “true” if the thread is running on which it is called else will give “ false” as it’s returning value/ 2. Another method is to implement join ( ) function. this method will wait until the thread on which it is called is terminated.

Both these methods are explained in detail with the examples below.

public class IsAliveExample {
 
  public static void main(String[] args) {
    System.out.println(Thread.currentThread().isAlive());
  }
}

The above program will always return true because it is being called within the main thread and which will always be alive during the call of isAlive method.

public class IsAliveExample {
 
  public static void main(String[] args) {
    Thread th = new MyOwnThread("A");
    th.start();
 
    // wait till the thread is alive
    while(th.isAlive());
 
    System.out.println("Thread is not alive any more.");
  }
}
 
class MyOwnThread extends Thread {
 
  private String threadName;
 
  public MyOwnThread(String name) {
    threadName = name;
  }
 
  public void run() {
 
    for(int i = 0; i < 1000; i++) {
     System.out.println("Thread " + threadName + " : " + i); 
    }
  }
 
}

Try the above code. Remember we are checking isAlive() for the thread called th and not the main method method.

public class JoinExample {
 
  public static void main(String[] args) {
 
    Thread th1 = new MyOwnThread("A");
    Thread th2 = new MyOwnThread("B");
 
    try {
      th1.start();      
      th1.join();
      th2.start();      
    }
    catch (InterruptedException e) {
 
    }
  }
}
 
class MyOwnThread extends Thread {
 
  private String threadName;
 
  public MyOwnThread(String name) {
    threadName = name;
  }
 
  public void run() {
 
    for (int i = 0; i < 1000; i++) {
      System.out.println("Thread " + threadName + " : " + i);
    }
  }
}

The above code guarantees that th2 will be executed only once th1 complete its execution. Remember that if you begin two threads simultaneously the output will never will the same in every execution. But in the above code you can control the output using join(). Try executing the same code without using join() you will find your answers.

Synchronization

It is basically the mechanism which helps two or more threads to share all the available resources in a sequential manner thus making sure that one resource is been used by only one single thread at a time thus avoiding the problem of collision or conflict between the threads and it is done in Java with the concept of “monitor” also named as “semaphore”.

The basic working mechanism of monitor works in a way that it works like a lock and this monitor can be owned by only one thread at a time and until the time this monitor or lock is been released by that particular thread the other threads are said to be in the waiting stage to acquire for that monitor or lock.

In Java we can enter into any monitor or lock by calling the method that has been modified with the synchronized keyword.

General form of the synchronized statement is as

synchronized(object) { 

// statements to be synchronized 

}

where object is a reference to the object being synchronized.

A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object’s monitor.

Interthread communication

Java implements a very efficient interprocess communication which reduces the CPU’s idle time to a very great extent. It is been implemented through wait ( ), notify ( ) and notifyAll ( ) methods. Since these methods are implemented as final methods they are present in all the classes.

The basic functionality of each one of them is as under:


wait( ) acts as a intimation to the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).

notify( ) is used as intimator to wake up the first thread that called wait( ) on the same object.

notifyAll( ) as the term states wakes up all the threads that called wait( ) on the same object. The highest priority thread will run first.


public class WaitNotifyAllExample {
 
  public static void main(String[] args) {
 
    try {
      Object o = new Object();
      Thread thread1 = new Thread(new MyOwnRunnable("A", o));
      Thread thread2 = new Thread(new MyOwnRunnable("B", o));
      Thread thread3 = new Thread(new MyOwnRunnable("C", o));
 
      // synchronized keyword acquires lock on the object.
      synchronized (o) {
        thread1.start();
        // wait till the first thread completes execution.
        // thread should acquire the lock on the object
        // before calling wait method on it. Otherwise it will
        // throw java.lang.IllegalMonitorStateException 
        o.wait();
        thread2.start();
        // wait till the second thread completes execution
        o.wait();
        thread3.start();
      }
 
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }
 
  }
}
 
class MyOwnRunnable implements Runnable {
 
  private String threadName;
 
  private Object o;
 
  public MyOwnRunnable(String name, Object o) {
    threadName = name;
    this.o = o;
  }
 
  public void run() {
 
 
    synchronized (o) {
      for (int i = 0; i < 1000; i++) {
        System.out.println("Thread " + threadName + " Count : " + i);
      }
      // notify all threads waiting for the object o.
      // thread should acquire the lock on the object
      // before calling notify or notifyAll method on it. 
      // Otherwise it will throw java.lang.IllegalMonitorStateException 
      o.notifyAll();
    }
  }
}

Deadlock

Deadlock as the name illustrates it is a special type of error that each programmer should make sure to avoid in a multitasking environment. This is a very difficult error to be debugged because it occurs once at a time when two threads time-slice in just the right way and other reason for a deadlock to occur is when it involves more than two words and two synchronized objects at a time.

It is illustrated in a better way with the help of an example.

Suspending, Resuming and stopping threads: Suspending a thread in java is quite an easy task and similarly we can resume that particular thread also in a very simple way. The thread can be suspended using suspend ( ) method, resumed with resume ( ) and stopped using stop ( ).

Suspend at times create serious troubles as it may happen that if a thread is suspended at a time when it has acquired some resources and now the other threads will be waiting for those resources hence causing the situation of a deadlock , so it is tried to be avoided.

The resume () is also avoided as it is the counterpart pf suspend ( ) and can’t be implemented without suspend ( ).

Stop( ) too sometimes ends up into serious trouble situations so Java 2 came up with a better alternative of run ( ) which will regularly keep a check as to when a thread should resume, suspend or stop its own execution and thus is based on the setting of a flag on each thread which determines the state as running means that the thread should be allowed to run, suspend denoted to be suspended and stop denoting the termination of that particular thread.

Personal tools
Interesting Sites
ListSergeant