JAVA REGION

Multithreaded Programming

Introduction:

A multithreaded 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, multithreading is a specialized form of multitasking.

Multitasking threads require less overhead than multitasking processes. Processes are
heavyweight tasks that require their own separate address spaces. Inter process communication
is expensive and limited. Context switching from one process to another is also costly. Threads,
on the other hand, are lightweight. They share the same address space and cooperatively
share the same heavyweight process. Inter thread communication is inexpensive, and context
switching from one thread to the next is low cost

Why Multithreading in java.?

While Java programs make use of process based
multitasking environments, process-based multitasking is not under the control of
Java. However, multithreaded multitasking is.

 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
program begins. The main thread is important for two reasons:

  • It is the thread from which other “child” threads will be spawned.
  • Often, it must be the last thread to finish execution because it performs various
    shutdown actions.


public class Test1 {

    public static void main(String[] args) {
        Thread thread = Thread.currentThread();
        System.out.println(thread);
        thread.setName("my thread");
        System.out.println(thread);
        for (int i = 0; i < 10; i++) {
            System.out.println(i);

            try {
                thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

}

output:

Thread[main,5,main]
Thread[my thread,5,main]
0
1
2
3
4
5
6
7
8

Download this code here

Packages and Interfaces

package shortPackageExample;

public class Balance {
    String name;
    double balance;

    public Balance(String name, double balance) {
        System.out.println("Dedfault Constructor");
        this.name=name;
        this.balance=balance;
        }

    void show() {
        if (balance < 0) {
            System.out.println("Low balance");

        } else {
            System.out.println("Balance is:" + balance);
        }
    }

}



package shortPackageExample;

public class Balance {
    String name;
    double balance;

    public Balance(String name, double balance) {
        System.out.println("Dedfault Constructor");
        this.name=name;
        this.balance=balance;
        }

    void show() {
        if (balance < 0) {
            System.out.println("Low balance");

        } else {
            System.out.println("Balance is:" + balance);
        }
    }

}

Module 1

1. What will be the answer..?

>>>>>>
package pckg1;

public class Test5 {
public static void main(String[] args) {
float f1 = 3.2f;
float f2 = 3.5f;
if (f1 == 3.2){
System.out.println("f1 is True");
}else{
System.out.println("f1 is False");
}
if (f2 == 3.5){
System.out.println("f2 is True");
}else{
System.out.println("f2 is False");
}
}
}
>>>>>>

Ans:
 f1 is False
f2 is True

2.What will be the Output...?

>>>>>>
package pckg1;

public class Test6 {

public static void main(String[] args) {
for (;;) {
System.out.println("siddu");

}

}

}


3.


EXCEPTION HANDLING....


Runtime errors can be divided into low-level errors that involve violating constraints, such as:
  • dereference of a null pointer
  • out-of-bounds array access
  • divide by zero
  • attempt to open a non-existent file for reading
  • bad cast (e.g., casting an Object that is actually a Boolean to Integer)
          and higher-level, logical errors, such as violations of a function's precondition:
  • call to Stack's "pop" method for an empty stack
  • call to "factorial" function with a negative number
  • call to List's nextElement method when hasMoreElements is false
          Logical errors can lead to low-level errors if they are not detected. Often, it is better to detect them (to provide better feedback).
  • When an error is detected, an exception is thrown. That is, the code that caused the error stops executing immediately, and control is transferred to the catch clause for that exception of the first enclosing try blockthat has such a clause. The try block might be in the current function (the one that caused the error), or it might be in some function that called the current function (i.e., if the current function is not prepared to handle the exception, it is "passed up" the call chain). If no currently active function is prepared to catch the exception, an error message is printed and the program stops.
  • Each catch clause specifies the type of one exception, and provides a name for it (similar to the way a function header specifies the type and name of a parameter). Java exceptions are objects, so the statements in a catch clause can refer to the thrown exception object using the specified name.
  • The finally clause is optional.
  • In general, there can be one or more catch clauses. If there is a finally clause, there can be zero catch clauses


Question 1: Assume that function f might throw exceptions Ex1, Ex2, or Ex3. Complete function g, outlined below, so that:
  • If the call to f causes Ex1 to be thrown, g will catch that exception and print "Ex1 caught".
  • If the call to f causes Ex2 to be thrown, g will catch that exception, print "Ex2 caught", and then will throw an Ex1 exception.
    static void g() throws ... {
        try {
      f();
  } catch ( ... ) {
            ...
        } ...
    }
Question 2: Consider the following function.
static void f(int k, int[] A, String S) {
    int j = 1 / k;
    int len = A.length + 1;
    char c;
   
    try {
        c = S.charAt(0);
        if (k == 10) j = A[3];
    } catch (ArrayIndexOutOfBoundsException ex) {
        System.out.println("array error");
  throw new InternalError();
    } catch (ArithmeticException ex) {
        System.out.println("arithmetic error");
    } catch (NullPointerException ex) {
        System.out.println("null ptr");
    } finally {
        System.out.println("in finally clause");
    }
    System.out.println("after try block");
}
Part A.
Assume that variable X is an array of int that has been initialized to be of length 3. For each of the following calls to function f, say what (if anything) is printed by f, and what, if any, uncaught exceptions are thrown by f.
A. f(0, X, "hi");
B. f(10, X, "");
C. f(10, X, "bye");
D. f(10, X, null);
Part B.
Why doesn't f need to have a throws clause that lists the uncaught exceptions that it might throw?

What is printed for each of the four runs?

  1. d caught Ex1
  2. c caught Ex2
     b caught Ex1
  3. b caught Ex3
  4. a caught Ex4
     execution stops due to uncaught exception Ex1 thrown in main
Question 1:

           static void g() throws Ex1, Ex3 {
               try {
                   f();
               } catch (Ex1 ex1) {
                   System.out.println("Ex1 caught");
               } catch (Ex2 ex2) {
                   System.out.println("Ex2 caught");
            throw new Ex1();
         }              
           }

Question 2:
Part A.

       A. f(0, X, "hi");
         nothing printed
         throws ArithmeticException
       B. f(10, X, "");
         prints "in finally clause"
         throws StringIndexOutOfBoundsException
       C. f(10, X, "bye");
         prints "array error", "in finally clause"
         throws InternalError
       D. f(10, X, null);
         prints "null ptr", "in finally clause", "after try block"
        

Part B.

Function f doesn't need to have a throws clause that lists the
uncaught exceptions that it might throw because only uncaught CHECKED
exceptions need to be listed in a function's throws clause.  The
uncaught exceptions that f might throw are all UNCHECKED exceptions.

Declaring your own Exception:

You can create your own exceptions in Java. Keep the following points in mind when writing your own exception classes:
·         All exceptions must be a child of Throwable.
·         If you want to write a checked exception that is automatically enforced by the Handle or Declare Rule, you need to extend the Exception class.
·         If you want to write a runtime exception, you need to extend the RuntimeException class.
We can define our own Exception class as below:
class MyException extends Exception{
}
You just need to extend the Exception class to create your own Exception class. These are considered to be checked exceptions. The following InsufficientFundsException class is a user-defined exception that extends the Exception class, making it a checked exception. An exception class is like any other class, containing useful fields and methods.

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception
{
   private double amount;
   public InsufficientFundsException(double amount)
   {
      this.amount = amount;
   }
   public double getAmount()
   {
      return amount;
   }
}
To demonstrate using our user-defined exception, the following CheckingAccount class contains a withdraw() method that throws an InsufficientFundsException.
// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount
{
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
   public void deposit(double amount)
   {
      balance += amount;
   }
   public void withdraw(double amount) throws
                              InsufficientFundsException
   {
      if(amount <= balance)
      {
         balance -= amount;
      }
      else
      {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   public double getBalance()
   {
      return balance;
   }
   public int getNumber()
   {
      return number;
   }
}
The following BankDemo program demonstrates invoking the deposit() and withdraw() methods of CheckingAccount.
// File Name BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      try
      {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}
Compile all the above three files and run BankDemo, this would produce the following result:
Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)


·         Exception can arise from different kind of situations such as wrong data entered by user, hardware failure, network connection failure, Database server down etc. In this section, we will learn how exceptions are handled in java.
·