Monday, 13 July 2015

Java Creating a Thread

In the most general sense, you create a thread by instantiating an object of type Thread. Java identifies two ways in which this can be accomplished:

(i) You can implement the Runnable interface.

(ii) You can extend the Thread class, itself.

1. Implementing Runnable


The easiest way to create a thread is to create a class that implements the Runnable interface. To implement Runnable, a class need only implement a single method called run():

public void run()

Inside the run() method, you will define the code that constitutes the new thread. The run() can call other methods, use other classes and declare variables, just like the main thread.

The only difference is that run() establishes the entry point for another, concurrent thread of execution within your program. This thread will end when run() returns.

After you create a class that implements Runnable, you will instantiate an object of type Thread from within that class using one of the following constructors:

Thread(Runnable threadObj)

Thread(Runnable threadObj, String threadName)

Here threadObj is the object whose run method is called and threadName is the name of the new thread.

After the new thread is created, it will not start running until you call start() method. The start() method puts the thread in the ready queue (runnable state). Whenever the thread gets scheduled its execution will start from the run() method.

Example:

class X implements Runnable
      public void run()
     { 
          for(int i=1; i<=5; i++)
          { 
               System.out.println("Child Thread: " + I);
          }

          System.out.println("Exiting child thread");

      }

}

class RunnableTest
     public static void main(String args[])
     { 
         X runnable  = new X();

         Thread ct = new Thread(runnable);

          ct.start();

          System.out.println("main thread exiting");

      }

}

Output:

main thread exiting

Child Thread: 1

Child Thread: 2

Child Thread: 3

Child Thread: 4

Child Thread: 5

Exiting child thread

Example:

class NewThread implements Runnable
     Thread t;

      NewThread()
     { 
         t = new Thread(this, "Demo Thread");

         System.out.println("Child thread: " + t);

         t.start();

     }

     public void run()
     { 
           for(int i=5; i>0; i--)
           {
                 try
                 { 
                       System.out.println("Child Thread: " + I);
                 }
                 catch(InterruptedException e)
                { 
                     System.out.println(e);
                }
      }

      System.out.println("Exiting child thread”);

      Thread.sleep(500);

    }

}

class ThreadDemo
     public static void main(String args[])
    { 
          new NewThread();
          try
          { 
               for(int n=5; n>0; n--)
               {
                   System.out.println("Main Thread: " + n);
                   Thread.sleep(1000);
               }
           }
           catch(InterruptedException e)
           {
                System.out.println("main thread interrupted");
            }
           System.out.println("main thread exiting");
     }
}

Output:

Child thread: Thread[Demo Thread,5,main]

Main Thread: 5

Child Thread: 5

Child Thread: 4

Main Thread: 4

Child Thread: 3

Child Thread: 2

Main Thread: 3

Child Thread: 1

Exiting child thread

Main Thread: 2

Main Thread: 1

main thread exiting

2. Extending Thread class

The second way to create a thread is to create a new class that extends Thread and then create an instance of that class. The extending class must override the run() method, which is the entry point for the new thread. It must also call start() to begin the execution of the new thread.

Example:

public class NewThread extends Thread
     NewThread()
     { 
            super("Demo Thread");
            System.out.println("Child thread: " + this);
            start();
      }

      public void run()
      { 
          for(int i=5; i>0; i--)
          { 
              try
              {
                  System.out.println("Child Thread: " + I);
                  sleep(500);
              }
              catch(InterruptedException e)
              {

              }

          }
          System.out.println("Exiting child thread");
          System.out.println(e);
     }
}

class ExtendThread
        public static void main(String args[])
        { 
            new NewThread();
            try
            { 
                for(int n=5; n>0; n--)
                {
                     System.out.println("Main Thread: " + n);
                     Thread.sleep(1000);
                }
             }
            catch(InterruptedException e)
            {
                 System.out.println("main thread interrupted");
            }
            System.out.println("main thread exiting");
       }
}

Output:

Child thread: Thread[Demo Thread,5,main]

Main Thread: 5

Child Thread: 5

Child Thread: 4

Main Thread: 4

Child Thread: 3

Child Thread: 2

Main Thread: 3

Child Thread: 1

Exiting child thread

Main Thread: 2

Main Thread: 1

main thread exiting

Note: If the thread is not assigned any name, it will be something like Thread-1, Thread-2, Thread-3 etc.

3. Choosing an Approach

The thread class defines several methods that can be overridden by a derived class. Out of these methods, the only one that must be overridden is run().

That is, of course, the same method required when you implement the Runnable interface. Many Java programmers feel that classes should be extended only when they are being enhanced or modified in some way.

So, if you will not be overriding any of Thread’s other methods, it is probably best simply to implement a Runnable interface.

Java The main thread

When a Java program starts up, one thread begins running immediately. This is usually called the main thread of your program because it is the one that is executed when your programs begins.

The main thread is the thread from which other “child” threads are created.

Although the main thread is created automatically when your program is started, it can be controlled through a Thread object. To do so, you must obtain a reference to it by calling the method currentThread(), which is public static member of Thread class. This method returns a reference to the thread in which it is called.

Once you have a reference to the main method, you can control it just like any other thread.

Example: The following example demonstrates how we can acquire reference of main thread and then access its properties using methods of Thread class.

class CurrentThreadDemo
     public static void main(String args[])
     { 
           Thread t = Thread.currentThread();
           System.out.println("Current thread: " + t);

           System.out.println("Name: " + t.getName());
           System.out.println("Priority: " + t.getPriority());

            t.setName("My Thread");

            t.setPriority(10);

            System.out.println("After name and priority change : " + t);

             System.out.println("New Name: " + t.getName());

             System.out.println("New Priority: " + t.getPriority());

             try
             { 
                    for(int n=5; n>0; n--)
                    { 
                         System.out.println(n);
                    }
             }
             catch(InterruptedException e)
             { 
                  System.out.println("main thread interrupted");
             }

             Thread.sleep(1000);
     }

}

Output:

Current thread: Thread[main,5,main]

Name: main

Priority: 5

After name and priority change : Thread[My Thread,10,main]

New Name: My Thread

New Priority: 10

5

4

3

2

1

The sleep() method in Thread might throw an InterruptedException, which is a checked exception. This would happen if some other thread wanted to interrupt this sleeping one.

Notice the output produced when t (thread reference) is used as an argument to println(). This displays in order: the name of the thread, its priority, and the name of its group. Its priority is 5, which is the default value, and main is also the name of the group of thread to which this thread belongs.

A thread group is a data structure that controls the state of a collection of threads as a whole.

Java The Thread class and the Runnable interface

Java’s multi-threading system is built upon the Thread class, its methods, and its companion interface, Runnable. This class belongs to package java.lang and hence there is no need of explicitly importing it.

Thread encapsulates a thread of execution, since you cannot directly refer to the internal state of a running thread, you will deal with it through its proxy, the Thread instance that spawned it. To create a new thread your program will either extend Thread class or implement the Runnable interface.

The Thread class defines several methods that help manage threads:


Java Messaging

When programming with most other languages, you must depend on the O.S. to establish communication between threads. This, of course, adds overhead.

By contrast, Java provides a clean, low-cost way for two or more threads to talk to each other, via calls to predefined methods that all objects have.

Java’s messaging system allows a thread to enter a synchronized method on an object, and then wait there until some other thread explicitly notifies it to come out of wait state.

Java Synchronization

Because multi-threading introduces an asynchronous behaviour to your programs, there must be a way for you to enforce synchronization when you need it.

For example, if you want two threads to communicate and share a complicated data structure, such as a linked list, you need some way to ensure that they do not conflict with each other.

That is, you must prevent one thread from writing data while another thread is in the middle of reading it. Java uses monitor for inter-thread synchronization.

You can think of a monitor as a very small box that can hold only one thread.

Once a thread enters a monitor, all other threads must wait until that thread exits the monitor. In this way, a monitor can be used to protect a shared asset from being manipulated by more than one thread at a time.

Most multi-threaded systems expose monitors as objects that your program must explicitly acquired and lock. Java provides a cleaner solution.

There is no class "monitor", instead, each object has its own implicit monitor that is automatically entered when one of the object's synchronized method is called.

Once a thread is inside a synchronized method no other thread can call any other synchronized method on the same object. This enables you to write very clear and concise multi-threaded code, because synchronization support is built into the language.