Basics Of Thread Programming – Part 3

                          Introduction to Java Thread Programming


Java language is well designed keeping in mind the thread related semantics. Every Java object has it's monitor, which will be obtained by the thread to lock it. Java offers the thread support in an object oriented fashion and its threading model is directly related to the native operating system's threading model. But on non-multithreaded environments, Java Virtual Machines are implemented to simulate the threads by JVM, and these threads are called green threads. So a java program may work different on different platforms depending on the threading features of those platforms.

Here are the most important features of java threads.
Following sections explain different concepts of thread lifecycle management and related APIs for programming the threads. While explaining the concepts only incomplete code pieces relevant to the context are shown. Complete source code of the sample is available for download from the website. There may be minor differences between the code snippets and the complete source code at the website. It is made for making the illustration more effective.

Thread Creation

Creation of threads in Java is to be done by creating the Thread class object. It can be done in two ways.

Create Subclass of java.lang.Thread

Create a subclass or derived class of java.lang.Thread class and instantiate it. Overload the run() method of Thread class with the code that has to be executed by the thread.
public class MyThread extends Thread
{
    // MyThread’s data and methods
      ……………………..

    public void run() {
                // code for executing the tasks the thread has to perform
            }
    }
    ……………………………
    ……………………………
    // create  a thread and let it be in created state
    Thread thread1 = new MyThread(…………);
    .............................

Implement  java.lang.Runnable Interface

Implement the java.lang.Runnable interface to make a thread class, create an object of it  and create an instance of java.lang.Thread class with Runnable implemented object passed as constructor parameter. Overload the run method of Runnable interface with the code that has to be executed by the thread.
public class MyRunnable implements Runnable
{
         // MyRunnable’s data and methods
         ……………………..

        public void run() {
                // code for
executing the tasks the thread has to perform
            }
        }
        ……………………………
}
……………………………
// create  a thread and let it be in created state
Thread thread2 = new Thread( new MyRunnable(…………) );

Start/Run the Thread

Thread’s execution can be started simply by invoking the start() method on the thread object created. It makes the new thread start it’s execution path and the thread which invoked start() method will proceed it’s execution  to the next instructions in its path.
// thread1 starts running, then  thread2 starts running, after that the  current thread(one that executed the statements “thread1.start();” and
// “thread2.start();” will proceed to execute the statements after them, i.e "
System.out.println" statement..
thread1.start();
thread2.start();
System.out.println(.........);
………………………….

Access the Current Thread

In Java current thread can be accessed by the static method of Thread class currentThread() which returns the reference to the thread making the call to the method. Apart from that the static methods on Thread class can be directly be invoked so that they will work on the current thread.  For example Thread.sleep(30) will make the current thread to sleep for 30 milliseconds.

Sleep the Thread

When a thread has nothing to do for a particular interval of time, then it can be slept by call to sleep() method on the thread. It takes millisecond and nanosecond parameters so that thread can be slept to that precision. After that time interval thread will wake  up automatically to execute the next instruction after the sleep method call.
……………………….
sleep(25); // invoked on the current thread object
……………………….
Thread.sleep(25);  // invoked on thread executing this statement
………………………..

Wakeup the Thread from sleep

Threads will wake up automatically after sleeping for a particular period of time. But their sleep can  be disturbed by force which is shown in the next few topics.

Suspend the Thread

Thread’s execution can be suspended indefinitely using suspend() method , but it introduces potential problems like deadlocks. That’s why this method is deprecated from many versions of Java. But the thread can still be suspended using the object monitor related methods wait() and notify() of java.lang.Object. Similarly thread’s suspension can be cancelled using the resume() method, which is also deprecated for the same reasons. It also can be simulated using the wait() and notify() methods.  

Object which is the base class for all the java objects has 3 interesting methods wait(), notify() and notifyAll(). Every object will have a monitor that acts like a lock for the object. When a thread obtains the monitor of the object, it can be thought that the thread has got the lock over the object. wait() method when invoked on a particular object,  it makes the thread to wait till it gets the monitor of the object to proceed with it’s execution. But when notify()/notifyAll() method is invoked it will make one or all the threads which are waiting for monitor over the object to wake up and obtain the monitor of the object. Only one will get the monitor and rest of them will wait for the monitor again. All this depends on how the wait() and  notify methods are used. wait() method can be used with or without time interval so that the waiting may be done for some time or indefinitely. notify() method will wakeup only 1 selected thread based on the policy of JVM implementation  and notifyAll will wakeup all the threads waiting for the monitor on the object.

To simulate the suspending and resuming of the threads we use the object monitor related methods wait() and notify(). The basic algorithm for it is  
  1. Consider two threads, slave thread, the thread that is to be suspended and resumed and the master thread which makes the slave thread to suspend and resume. 
  2. A boolean variable is used to indicate the slave thread if thread should be in suspended state or not.
  3. In run method of the slave thread( or in any method called from run) check from time to time the boolean variable’s value to decide if thread has to be suspended state or not. If thread has to be suspended invoke wait() method after ensuring that the thread has obtained lock over the object(using synchronized statement). This makes the thread enter the wait state which is equivalent to suspended state because thread is not executing any instructions.
public class MyThread extends Thread {
        ………………………………
public boolean suspended = false;
……………………………….
public void run()  {
      try {            
          // basic initialization for thread run
          int i=0;
          // let this thread run infinitely till the thread is interrupted by master thread    
          while(true) {
                  // when the thread is told to be suspended by master thread ( by setting its value to true)
                  // if thread don’t have to be suspended then master thread will set this to false so that wait() wont be called
                  while(suspended){
                          // obtain a lock over the current thread object , synchronized(this) makes it thread safe
                          synchronized(this) {
                          //wait() forces the thread to wait, which is equivalent to suspension of the thread
                          // when this thread has to be resumed then notify() will be called by the master thread   
                          wait();
                 }
           }
           //normal work to be done by thread, i.e updating the progress bar
           i = (i+1)%100;
           progressBar.setValue(i);
           //dalay that makes the progress bar updated slowly so that it can be viewed comfortably
           sleep(25);
}

      }catch(InterruptedException iex){
      
      } catch(Exception ex) {
          ex.printStackTrace();
      }
  } // end of run() method
}// end of MyThread class
4.    When ever the thread has to be suspended, then master thread will change the  value of the boolean variable to true.  At beginning it’s value will be false. When it’s value turns to true, the slave thread calls wait() method due to changed value.
//When suspend button is clicked change the varaiable/flag to true that forces the slave thread to invoke wait()  
void button_Suspend_actionPerformed(ActionEvent e)
  {
        ((MyThread)thread1).suspended = true;
        …………………………………………..
  }

5.    When ever thread has to be resumed from suspended state, master thread’s notify() method call will wake the thread from its waiting state. This is similar to resuming the thread from suspension. For invoking notify(), lock has to be obtained on the object. Also the boolean variable has to be changed to false, because it should go back to suspended state immediately after it is resumed.  
//method handler for button press asking to resume the thread
void button_Resume_actionPerformed(ActionEvent e)  {
         // set the flag to false so that the thread wont go back to waiting state immediately after it is awaken    
        ((MyThread)thread1).suspended = false;
         // obtain a lock over the thread object , synchronized(this) makes it thread safe    
        synchronized(thread1){
               //make the thread wake up from it’s waiting state,  just like resuming
               thread1.notify();
        }
        …………………………………
}    

Resume the Thread

Thread’s indefinite suspension can be put to an end by resuming it using the method resume(), but it introduces potential problems like deadlocks. That’s why this method is deprecated from many versions of Java. But the thread can still be suspended and resumed using the object monitor related methods like wait() and notify(). Please refer to the section “Suspend the Thread” to know how to do the simulation of suspending and resuming the thread.

Name the Thread

Thread’s name can be set by giving the name as the parameter to the thread’s constructor. Apart from that threads name can be set using setName() method. Also the thread’s name can be obtained using getName() method.
………………………
// Creates 2 threads with names T1and T2
Thread thread1 = new MyThread(threadGroup, progressBar1, "T1");
Thread thread2 = new Thread(threadGroup, new MyRunnable(progressBar2), "T2");
…………………………
// rename T1 to Thread#1 and T2 to Thread#2
thread1.setName( "Thread#1");
thread2.setName( "Thread#2");
…………………………
// get the names of the threads
System.out.println("Created Thread:"+thread1.getName());
System.out.println("Created Thread:"+thread2.getName());

Set Priority to the Thread

Thread’s priority level can be set as normal, minimum or maximum. These 3 levels will be mapped to one of the many thread levels defined by the underlying operating system. Java’s thread priority levels will be mapped drastically differently on different operating systems based on the threading model that the operating system defines.  Thread priority can be defined using setPriority() method and thread level defining constants Thread . MAX_PRIORITY, Thread . NORM_PRIORITY and Thread . MIN_PRIORITY. Also the priority level of a thread can be obtained using the method getPriority(). Effectiveness of thread priorities is dependent on many factors like the implementation of JDK, kind of tasks the threads are performing, mapping of thread priorities to the operating system thread priorities, priority of the process,  etc.  
…………………………………….
// set the priority to minimum
thread1.setPriority(Thread.MIN_PRIORITY);
…………………………
// get the threads priority
System.out.println("Created Thread:"+thread1.getName()+", with Priority:"+thread1.getPriority());  
…………………………………….

Group the Threads

Threads can be bundled into a group so that the operations can be done on all the threads collectively with single method calls. For example if  interrupt() method is called on a thread group, it is equivalent to invoking the  interrupt() method on each of the threads in that thread group.
…………………………….
// if thread1 and thread2 are in threadGroup, interrupt() can be called on threadGroup instead of calling it on thread1 and
// thread2 individually
threadGroup.interrupt();
……………………………..
Threads can be added to a thread group by passing the thread group object’s reference to the constructor of the thread object. Thread can access the ThreadGroup to which it belongs using getThreadGroup() method. ThreadGroups can contain both threads and threadgroups just as a filesystem directory can hold both files and directories.
……………………………
// create  a new threadgroup
ThreadGroup threadGroup = new ThreadGroup("MyThreadGroup");
System.out.println("Created ThreadGroup:"+threadGroup.getName()+", on the Thread:"+Thread.currentThread().getName() );
// create thread  so that it belongs to the thread group created above
Thread thread1 = new MyThread(threadGroup, progressBar1,"T1");
// Get the threadgroup(and it’s name) to which the thread belongs to
System.out.println("Created Thread:"+thread1.getName()+”, for ThreadGroup:"+thread1.getThreadGroup().getName());

Stop the Thread

Thread’s execution can be stopped in two ways. One way is when the run() method is executed completely and the control returns from that method. The other way is stopping the thread by force using the method like interrupt(), stop() etc. stop() method is deprecated because it is source of some problems. So interrupt() is considered to be the safe method to stop the execution of the thread. To check if a thread is really interrupted or not, use interrupted(0 or isInterrupted() methods which returns boolean value to inform if a thread is interrupted or not. In some versions of java the thread with maximum priority cannot be interrupted.
……………………………………
// interrupt the thread
thread1.interrupt();
……………………………………
// interrupt all the threads in the thread group
threadGroup.interrupt();         
……………………………………
// check if thread is interrupted, if it is not , then raise error
if(thread1.isInterrupted()==true) {
            System.out.println("Stopped the execution of Thread:"+thread1.getName());
}
else {    
            System.out.println("Failed to stop the execution of Thread:"+thread1.getName());
            JOptionPane.showMessageDialog(this, "Failed to stop the execution of Thread:"+thread1.getName());
}   
.......................................................

Destroy the Thread

Thread can be destroyed in a normal  way and also by force. Destruction of the thread can be done normally by stopping the thread and let it destruct. It is the safer way to destruct the thread. But thread can be destructed by force in special conditions like termination of a program etc where it doesn’t matter what locks and monitors are being used. Use destroy() method of the Thread class  to destroy the thread by force, and the monitors and locks will remain  undisturbed, which is a side effect.

SourceCode Description

MainFrame.java

MainFrame class has the GUI and the event handling functionality. It is derived from JFrame swing class  and it has a panel to which the buttons and the GUI controls are added. initThreads() method creates the threads from MyRunnable and MyThread classes and associates those threads with the thread group. Rest of the methods are for creating the GUI and event handling etc. In the event handling methods the thread classes are manipulated as per the requirement.  

MyThread.java

MyThread class is a thread class derived from java.lang.Thread class. From the constructor it gets the thread group to which it belongs to, name of the thread and the progress bar with which it’s going to work. In run() method it has the code for changing the progress of the progress bar from time to time. Also it has the code for simulating suspend and resume states of the thread. This class demonstrates creation of thread from a subclass of java.lang.Thread and simulation of suspending and resuming the thread with wait()/notify() method pair of java.lang.Object class.

MyRunnable.java

    MyRunnable class is a thread class implementing java.lang.Runnable interface. From the constructor it gets the progress bar with which it’s going to work. The instance of this class will be associated with the instance of java.lang.Thread instance, which will be associated to the thread group. In run() method it has the code for changing the progress of the progress from time to time. This class demonstrates creation of thread from the implementation class of java.lang.Runnable interface and suspending and resuming the thread with deprecated methods of java.lang.Thread class.