Monday, 13 July 2015

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.

Java Thread Life Cycle (Thread States)

Thread exists in several states. A thread can be running. It can be ready to run as soon as it gets CPU time. 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.

1. Newborn State

When we create a thread object, the thread is born and is said to be in newborn state. The thread is not yet scheduled for running. At this state, we can do only one of the following things with it:

1. Schedule it for running using the start() method.

2. Kill it using stop() method

If scheduled, it moves to runnable state. If we attempt to use any other method at this stage, an exception will be thrown.

2. Runnable State

The runnable state means that the thread is ready for execution and is waiting for the availability of the processor. That is, the thread has joined the queue of threads that are waiting for execution. If all threads are of equal priority, then normally they are given time slots for execution in round robin fashion. The thread that relinquishes control joins the queue at the end and again waits for its run. However, if we want a thread to relinquish control to another thread of equal priority before its turn comes, it can do so by invoking the yield() method.

3. Running State

Running means that the processor has given its time to the thread for its execution. The thread runs until it relinquishes control on its own or it is pre-empted by a higher priority thread.

A running thread may relinquish its control in one of the following situations:

  • Its time-slice is over
  • It is pre-empted by a higher priority thread
  • It yields i.e. voluntarily gives up control.
  • It has completed its execution
  • It is stopped by some other thread.
  • It has been suspended using suspend() method; a suspended thread can be revived by using the resume() method. This approach is useful when we want to suspend a thread for some time due to certain reason, but do not want to kill it.
  • It has been made to sleep. We can put a thread to sleep for a specified time period using the static method sleep(time) of Thread class where time is in milli-seconds. This means that the thread is out of the queue during the time period. The thread re-enters the runnable state as soon as this time period is elapsed.
  • It has been told to wait until some event occurs. This is done using the wait() method. The thread can be scheduled to run again using the notify() method.
  • It is performing some I/O operation.

4. Blocked State

A thread is said to be blocked when it is prevented from entering into the runnable state and subsequently the running state. 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.

5. Dead State

Every thread has a life cycle. A running thread ends its life when it has completed executing its run() method. It has a natural death. However, we can kill it by sending the stop message to it at any state thus causing a premature death. A thread can be killed as soon as it is born, or while it is running, or even when it is in “not runnable” (blocked condition).

Wednesday, 8 July 2015

Java Multi-Threaded Programming

1. Introduction

A thread is a single flow of control within a program. Thread is very much similar to a process. In fact, the thread is also called a lightweight process.

1.1 Thread v/s Process

Normally different processes occupy different memory space. When the CPU shifts from one process to another process, the state of the currently running process is saved and the state of another process is restored. No useful work is being done during state switch. This is referred to as context switch. The context switch time should be as less as possible to maximize the CPU utilization.

Threads are also like independent processes but they share the same memory and state. The separate threads also have separate state but the state is very small as compared to process state.

The state may contain just program counter and stack pointer. So switching from one thread to another thread takes very little time. Thus the context switch time for threads is very small as compared to the process. Hence CPU utilization is high in case of multiple threads as compared to the utilization in case of multiple processes. Threads are also referred to as light-weight process.

1.2 Multi-Threaded program

A multi-threaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution. Thus, multi-threading is a specialized form of multi-tasking.

For example, a program may have three threads:

  • One handling the printing
  • One handling the editing
  • One downloading a file from the Internet.

All these threads might be running concurrently thus maximizing the CPU utilization.

1.3 Process-based Multi-tasking


Most of the operating systems allow you to run two or more programs at the same time. It is referred to as process-bases multi-tasking. For example, you can run a Java program and at the same time you may be editing a word document. The process-based multi-tasking ensures that there will be some program to be executed most of the time so it increases the CPU utilization.  

In process-based multi-tasking, a program is the smallest unit of code that can be dispatched by the scheduler.

1.4 Thread-based multi-tasking

Thread is the smallest unit of execution in a thread-based multi-tasking environment. A process can be divided into a number of threads executing concurrently. This allows us to handle more than one task concurrently in a single program. For example, you can edit a word document and at the same time print a portion of it or another document.

Thread-based multi-tasking improves CPU utilization just like process-based multi-tasking. But at the same time it effectively speeds up the execution of a single program by executing its different parts concurrently in separate threads.

Thus process based multi-tasking deals with the “big picture”, and thread-based multi-tasking handles the details.

1.5 The Java Thread Model

The Java run-time system depends on threads for many things, and all the class libraries are designed with multi-threading in mind. In fact, Java uses threads to enable the entire environment to be asynchronous. This helps reduce inefficiency by preventing the waste of CPU cycles.

Single threaded systems use an approach called an event loop with polling. In this model, a single thread of control runs in an infinite loop, polling a single event queue to decide what to do next. In a single threaded environment, when a thread blocks (that is, suspends execution) because it is waiting for some resource, the entire program stops running.

The benefit of Java's multi-threading is that the main loop/polling mechanism is eliminated.

When a thread blocks in Java program, only the single thread that is blocked pauses, all other threads continue to run.