Are You Feeling any difficulity while writing Core-Java Programs. Send those to me Here.

Multi threading

Multi threading

Unit Structure

9.0 Objective: In this lesson of Java Tutorial, you will learn...
9.1 Introduction:
9.2 Overview:
9.3.1 Thread Life cycle:
9.3.2 Advantages of multithreading over multi-tasking:
9.3.3 Thread Creation and simple programs:
9.3.4 Synchronized threads:
9.3.4.1 Synchronized Methods:
9.4 Summary:
9.5 List of references:
9.6 Bibilography:
9.7 Model answers

9.0 Objective: In this lesson of Java Tutorial, you will learn...



  • Thread life cycle 
  • How to create thread 
  • Advantages of threading


9.1 Introduction:

A thread is defined as a separate stream of implementation that takes place simultaneously with and independently of everything else that might be happening. It does not have an event loop. A thread runs autonomously of anything else happening in the computer. With threads the other tasks that don't get stuck in the loop can continue processing without waiting for the stuck task to terminate. A thread is a coding that doesn't affect the architecture of an application. Threading is equally separate the computer's power among different tasks.

9.2 Overview:

Threading concept is very important in Java Programing language. A thread is a sequential path of code execution within a program. And each thread has its own local variables, program counter and lifetime. In Java, an object of the Thread class can represent a thread. Thread can be implemented through any one of two ways:
Using threads in Java will enable greater flexibility to programmers looking for that extra edge in their programs. The simplicity of creating, configuring and running threads lets Java programmers devise portable and powerful applets/applications that cannot be made in other third-generation languages. Threads allow any program to perform multiple tasks at once. In an Internet-aware language such as Java, this is a very important tool.

9.3.1 Thread Life cycle:

When you are programming with threads, understanding the life cycle of thread is very valuable. While a thread is alive, it is in one of several states. By invoking start() method, it doesn‘t mean that the thread has access to CPU and start executing straight away. Several factors determine how it will proceed.
Different states of a thread are:


1. New state – After the construction of Thread instance the thread is in this state but before the start() method invocation. At this point, the thread is considered not alive.

2. Runnable (Ready-to-run) state – A thread start its life from Runnable state. A thread first enters runnable state after the invoking of start() method but a thread can come again to this state after either running, waiting, sleeping or coming back from blocked state also. On this state a thread is waiting for a turn on the processor.
3. Running state – A thread is in running state that means the thread is presently executing. There are numerous ways to enter in Runnable state but there is only one way to enter in Running state: the scheduler select a thread from runnable pool.
4. Dead state – A thread can be considered dead when its run() method completes. If any thread comes on this state that means it cannot ever run again.
5. Blocked - A thread can enter in this state because of waiting the resources that are hold by another thread.

9.3.2 Advantages of multithreading over multi-tasking:

1. Reduces the computation time.
2. Improves performance of an application.
3. Threads distribute the same address space so it saves the memory.
4. Context switching between threads is usually less costly than between processes.
5. Cost of communication between threads is comparatively low.


9.3.3 Thread Creation and simple programs:

In Java, an object of the Thread class can represent a thread. Thread can be implemented through any one of two ways:


  • Extending the java.lang.Thread Class 
  • Implementing the java.lang.Runnable Interface




Fig 9.3: Creation of thread 


  • Extending the java.lang.Thread Class

Syntax: class MyThread extends Thread

{
}


  • Implementing the java.lang.Runnable Interface

Syntax: MyThread implements Runnable

{
}


  • After declaration of thread class, we have to override run( ) method in class. 
  • Now we can create object of thread if needed.

In short we have to follow following these steps:

1. Extend the java.lang.Thread Class.
2. Override the run( ) method in the subclass from the Thread class to define the code executed by the thread.
3. Create an instance of this subclass. This subclass may call a Thread class constructor by subclass constructor.
4. Invoke the start( ) method on the instance of the class to make the thread eligible for running.

The following program demonstrates a single thread creation extending the "Thread" Class:

class MyThread extends Thread
{
String s=null;
MyThread(String s1)
{
s=s1;
start();
}
public void run()
{
System.out.println(s);
}
}
public class RunThread
{
public static void main(String args[])
{
MyThread m1=new MyThread("Thread started....");
}
}

Output of the Program is :


C:\>javac RunThread.java

C:\>java RunThread

Thread started....


II. Implementing the java.lang.Runnable Interface


The procedure for creating threads by implementing the Runnable Interface is as follows:

1. A Class implements the Runnable Interface, override the run() method to define the code executed by thread. An object of this class is Runnable Object.
2. Create an object of Thread Class by passing a Runnable object as argument.
3. Invoke the start( ) method on the instance of the Thread class.

The following program demonstrates the thread creation implenting the Runnable interface:


class Thr1 implements Runnable{

Thread t;
String s=null;
Thr1(String s1){
s=s1;
t=new Thread(this);
t.start();
}
public void run(){
System.out.println(s);
}
}

public class RunableThread{

public static void main(String args[]){
Thr1 m1=new Thr1("Thread started....");
}
}

Output:

C:\>javac RunableThread.java
C:\>java RunableThread
Thread started....

However, this program returns the output same as of the output generated through the previous program.

There are two reasons for implementing a Runnable interface preferable to extending the Thread Class:
1. If you extend the Thread Class, that means that subclass cannot extend any other Class, but if you implement Runnable interface then you can do this.
2. The class implementing the Runnable interface can avoid the full overhead of Thread class which can be excessive.

join() & isAlive() methods:

The following program demonstrates the join() & isAlive() methods:

class DemoAlive extends Thread {

int value;
public DemoAlive(String str)
{
super(str);
value=0;
start();
}
public void run()
{
try
{
while (value < 5) {
System.out.println(getName() + ": " + (value++));
Thread.sleep(250);
}
} catch (Exception e) {}
System.out.println("Exit from thread: " + getName());
}
}
public class DemoJoin
{
public static void main(String[] args)
{
DemoAlive da = new DemoAlive("Thread a");
DemoAlive db = new DemoAlive("Thread b");
try
{
System.out.println("Wait for the child threads to finish.");
da.join();
if (!da.isAlive())
System.out.println("Thread A not alive.");
db.join();
if (!db.isAlive())
System.out.println("Thread B not alive.");
} catch (Exception e) { }
System.out.println("Exit from Main Thread.");
}
}
Output:
C:\>javac DemoJoin.java
C:\>java DemoJoin
Wait for the child threads to finish.
Thread a: 0
Thread b: 0
Thread a: 1
Thread b: 1
Thread a: 2
Thread b: 2
Thread a: 3
Thread b: 3
Thread a: 4
Thread b: 4
Exit from thread: Thread a
Thread A not alive.
Exit from thread: Thread b
Thread B not alive.
Exit from Main Thread.

9.3.4 Synchronized threads:

In Java, the threads are executed separately to each other. These types of threads are called as asynchronous threads. But there are two problems may be occurs with asynchronous threads.


  • Two or more threads share the similar resource (variable or method) while only one of them can access the resource at one time. 
  • If the producer and the consumer are sharing the same kind of data in a program then either producer may make the data faster or consumer may retrieve an order of data and process it without its existing.

Suppose, we have created two methods as increment( ) and decrement( ). which increases or decreases value of the variable "count" by 1 respectively shown as:


public void increment( ) {

count++;
}

When the two threads are executed to access these methods (one for increment( ),another for decrement( )) then both will distribute the variable "count". in that case, we can't be sure that what value will be returned of variable "count". We can see this problem in the diagram shown below:


To avoid this problem, Java uses monitor also known as ―semaphore‖ to prevent data from being corrupted by multiple threads by a keyword synchronized to coordinate them and intercommunicate to each other. It is basically a mechanism which allows two or more threads to share all the available resources in a sequential manner. Java's synchronized is used to ensure that only one thread is in a critical region. Critical region is a lock area where only one thread is run (or lock) at a time. Once the thread is in its critical section, no other thread can enter to that critical region. In that case, another thread will has to wait until the current thread leaves its critical section.


General form of the synchronized statement is as:


synchronized(object) {

// statements to be synchronized
}
Lock:
Lock term refers to the access approved to a particular thread that can access the shared resources. At any given time, only one thread can hold the lock and thereby have access to the shared resource. Every object in Java has build-in lock that only comes in action when the object has synchronized method code. By associating a shared resource with a Java object and its lock, the object can act as a guard, ensuring synchronized access to the resource. Only one thread at a time can access the shared resource guarded by the object lock.
Since there is one lock per object, if one thread has acquired the lock, no other thread can acquire the lock until the lock is not released by first thread. Acquire the lock means the thread currently in synchronized method and released the lock means exits the synchronized method.

Remember the following points related to lock and synchronization:




  • Only methods (or blocks) can be synchronized, Classes and variable cannot be synchronized. 
  • Each object has just one lock. 
  • All methods in a class need not to be coordinated. A class can have both synchronized and non-synchronized methods. 
  • If two threads wants to execute a synchronized method in a class, and both threads are using the similar instance of the class to invoke the method then only one thread can execute the method at a time. 
  • If a class has both synchronized and non-synchronized methods, multiple threads can still access the class's non-synchronized methods. 
  • If you have methods that don't access the data you're trying to protect, then you don't need to synchronize them. Synchronization can cause a hit in several cases (or even deadlock if used incorrectly), so you should be careful not to overuse it. 
  • If a thread goes to sleep, it holds any locks it has—it doesn't let go them. 
  • A thread can obtain more than one lock. For example, a thread can enter a synchronized method, thus acquiring a lock, and then directly invoke a synchronized method on a different object, thus acquiring that lock as well. As the stack unwinds, locks are unrestricted again. 
  • You can synchronize a block of code rather than a method. 
  • Constructors cannot be synchronized


9.3.4.1 Synchronized Methods:

Any method is specified with the keyword synchronized is only executed by one thread at a time. If any thread wants to implement the synchronized method, firstly it has to obtain the objects lock. If the lock is already held by another thread, then calling thread has to wait. Synchronized methods are useful in those situations where methods are executed concurrently, so that these can be intercommunicate control the state of an object in ways that can corrupt the state if . Stack implementations usually define the two operations push and pop of elements as synchronized, that‘s why pushing and popping are mutually exclusive process. For Example - if several threads were sharing a stack, if one thread is popping the element on the stack then another thread would not be able to pushing the element on the stack.

The following program demonstrates the synchronized method:


class Demo extends Thread{

static String msg[]={"This", "is", "a", "synchronized", "variable"};
Share(String threadname){
super(threadname);
}
public void run(){
display(getName());
}
public synchronized void display(String threadN){
for(int i=0;i<=4;i++)
System.out.println(threadN+msg[i]);
try{
this.sleep(1000);
}catch(Exception e){
}
}
}

public class SynThread1 {

public static void main(String[] args) {
Share t1=new Share("Thread One: ");
t1.start();
Share t2=new Share("Thread Two: ");
t2.start();
}
}

Output of the program is:


Thread One: variable

Thread Two: This
Thread Two: is
Thread two: a
Thread Two: synchronized
Thread Two: variable
C:\nisha>javac SynThread.java
C:\nisha>java SynThread
Thread One: This
Thread One: is
Thread One: a
Thread One: synchronized
Thread One: variable
Thread Two: This
Thread Two: is
Thread two: a
Thread Two: synchronized
Thread Two: variable

9.4 Summary:

A thread executes a series of instructions. Every line of code that is executed is done so by a thread. In Java, the threads are executed independently to each other. Multithreading is vital to Java for two main reasons. First, multithreading enables you to write very efficient programs because it lets you utilize the idle time that is present in most programs. Most I/O devices, whether they be network ports, disk drives, or the keyboard, are much slower than the CPU. Thus, a program will often use a majority of its execution time waiting to send or receive information to or from a device. By using multithreading, your program can execute another task during this idle time. For example, while one part of your program is sending a file over the Internet, another part can be
handling user interaction (such as mouse clicks or button presses), and still another can be buffering the next block of data to send.
The second reason that multithreading is important to Java relates to Java‘s eventhandling model. A program (such as an applet) must respond speedily to an event and then return. An event handler must not retain control of the CPU for an extended period of time.


9.7 Model answers

1) What are the two ways to create the thread?
Ans : 1.by implementing Runnable 2.by extending Thread

2) Explain the advantages of threading?

Ans : Advantages of multithreading over multi-tasking:
1. Reduces the computation time.
2. Improves performance of an application.
3. Threads distribute the same address space so it saves the memory.
4. Context switching between threads is usually less costly than between processes.
5. Cost of communication between threads is comparatively low.

3) What are synchronized methods and synchronized statements? Ans : Synchronized methods are methods that are used to control access to an object. A thread only executes a synchronized method after it has acquired the lock for the method's object or class. Synchronized statements are similar to synchronized methods. A synchronized statement can only be executed after a thread has acquired the lock for the object or class referenced in the synchronized statement.


4) Explain the states of a tread?

Ans : There are five states:
01New state – After the construction of Thread instance the thread is in this state but before the start() method invocation. At this point, the thread is considered not alive.
6. Runnable (Ready-to-run) state – A thread start its life from Runnable state. A thread first enters runnable state after the invoking of start() method but a thread can come again to this state after either running, waiting, sleeping or coming back from blocked state also. On this state a thread is waiting for a turn on the processor.
7. Running state – A thread is in running state that means the thread is presently executing. There are numerous ways to enter in Runnable state but there is only one way to enter in Running state: the scheduler select a thread from runnable pool.
8. Dead state – A thread can be considered dead when its run() method completes. If any thread comes on this state that means it cannot ever run again.
9. Blocked - A thread can enter in this state because of waiting the resources that are hold by another thread.
7) What is a thread?
A: In Java the Thread class represents a single independent path of execution in a Java Virtual Machine. When you run a Java program it implicitly starts a single thread of execution. The Thread class enables programmers to create additional threads and set them running. A number of threads may run in parallel, but only one is actively executed at a given moment.
The Java runtime system uses fairly complex thread scheduling mechanisms to coordinate the execution of threads, but this does not require privileged knowledge or detail level intervention by programmers. Programmers can manage the high level creation, initiation and distribution of tasks amongst threads through simple API methods.
The example below shows the simplest approach to thread creation and task execution; construct a new Thread with a Runnable argument and start it.
8) How to create one or more threads in Java?
Ans : program
public class Demo implements Runnable
{
public static void main(String args[]) throws Throwable
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
new Thread(obj1).start();
new Thread(obj2).start();
// main thread is ending here,
// Thread-0 and Thread-1 continue to run.
}
public void run()
{
try {
for (int i=0; i<5; i++) {
System.out.println("thread "
+Thread.currentThread().getName()+" step "+i);
Thread.sleep(500);
}
} catch (Throwable t) { }
}
}
Output:
C:\Java\jdk1.5.0_01\bin>java Demo
thread Thread-0 step 0
thread Thread-1 step 0
thread Thread-0 step 1
thread Thread-1 step 1
thread Thread-0 step 2
thread Thread-1 step 2
thread Thread-0 step 3
thread Thread-1 step 3
thread Thread-0 step 4
thread Thread-1 step 4
C:\Java\jdk1.5.0_01\bin>
9) Implementation of the multithreads by extending Thread Class.
Ans :
class Thr1 extends Thread{
Thr1(String s){
super(s);
start();
}
public void run(){
for(int i=0;i<7;i++){
System.out.println("Name of thread:"
+Thread.currentThread().getName());
try{
Thread.sleep(1000);
}catch(Exception e){}
}
}
}
public class Demo{
public static void main(String args[]){
System.out.println("Thread Name :"
+Thread.currentThread().getName());
Thr1 m1=new Thr1("Thread 1");
Thr1 m2=new Thr1("Thread 2");
}
}
Output:
C:\Java\jdk1.5.0_01\bin>java Demo
Thread Name :main
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2
Name of thread:Thread 1
Name of thread:Thread 2



No comments:

Post a Comment