Monday, 13 July 2015

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.

Java Thread Priorities

Java assigns to each thread a priority that determines how that thread should be treated with respect to the others.

Thread priorities are integers that specify the relative priority of one thread to another. As an absolute value, a priority is meaningless; a higher-priority thread does not run any faster than a lower-priority thread if it is the only thread running. Instead, a thread’s priority is used to decide when to switch from one running thread to next. This is called a ontext switch.

The rules that determine when a context switch takes place are simple:

  • A thread can voluntarily (on its own) relinquish control. This is done by explicitly yielding, sleeping or blocking on pending I/O. In this scenario, all other threads are examined, and normally the highest-priority thread that is ready to run is given the CPU.

  • A thread can be pre-empted by a higher-priority thread. In this case, a lower priority thread that does not yield the processor is simply pre-empted 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. Some OS support non-preemptive priority based scheduling. In such case a high priority thread gets chance only when low priority thread completes.
  • In cases where two threads with the same priority are competing for CPU cycles, the situation is a bit complicated. For OS such as windows 98, threads of equal priority are normally time-sliced automatically in the round-robin fashion. For other types of OS's, thread of equal priority must voluntarily (on their own) yield (give) control to their peers. If they do not, the other threads will not run.

Note: Problems can arise from the differences in the way that O.S.’s context-switch threads of equal priority.