Date Archives July 26, 2016

Wait() vs. Sleep()

Wait and sleep method are completely different to each other

  • wait() & notify(): method for inter thread communication.
  • sleep(): introducing small pause during thread execution.

Screen Shot 2016-07-26 at 2.49.35 PM

wait() & notify()

  • wait() method puts a thread on wait
    • For example, in Producer Consumer problem, producer thread should wait if Queue is full or Consumer thread should wait if Queue is empty.
  • notify()  & notifyAll() method is used to wake up waiting thread by communicating that waiting condition is over now
    • For example, once producer thread puts an item on empty queue it can notify Consumer thread that Queue is not empty any more.
    • notify(): wakes up one thread
    • notifyAll(): wakes up all the threads (use this when you are not sure which one to use)
Example...
/*
   Until pizza arrives, eatPiazza will in wait
   If pizzaGuy() executed, it will wake up eatPiazza()
   by using notifyAll();
*/
class MyHouse{
   private boolean pizzaArrived = false;
   
   public void eatPizza(){
      synchronized(this){
         while(!pizzaArrived){
            wait();
         }
      }
      System.out.println("yumyum...");
   }

   public void pizzaGuy(){
      synchronized(this){
         this.pizzaArrived = true;
         notifyAll();
      }
   }
}

sleep()

  • sleep() hold a lock, doesn’t release any lock or monitor while sleeping.
  • When a Thread goes to Sleep it can be either wake up normally after sleep duration elapsed or it can be woken up abnormally by interrupting it.
Example...
/*
   It will print out count string one at a time
   with a 3 seconds term
*/
public class Example{
   public static void main(String[] args){
      String count[] = ("One","Two","Three","Four","Five");

      for(int i=0; i<count.length;i++){
         Thread.sleep(3000);             // sleep for 3 seconds
          System.out.println(count[i]);  // printout count string
      }
   }
}

Synchronized in Thread

synchronized

  • While running multi-threads, there will be a significant problem when those threads try to use same resource.
    • For example, multiple people try to deposit money into the same account. Let’s say initial balance is $0. If 5 people are accessing at the same time, they all will see $0 as an account balance. Then, after all people’s deposit of $500 each, it will have $500 for total deposit. This is because they accessed at the same time, and they all updated balance as $500. However, the balance should be $2,500.
  • So, lock is needed to avoid other thread trying to use the same resource at the same time.
  • That lock can be done by Synchronized.

There is two ways to use synchronized.

  • Synchronized method
public synchronized /* Method name  */(){
   ...
}
  • Synchronized block
synchronized( /* Object to be shared */ ){
   ...
}

Primitive type vs. Reference type

Primitive vs Reference Type Java

Primitive type

  • Basic types for characters, different kinds of integers, and different kinds of floating point numbers (numbers with a decimal point), and also types for the values true and false – char, int, float, and bool. All of these basic types are known as primitive types.
  • The value of the variable is stored in the memory location assigned to the variable. For example, if an integer variable is declared as “int a = 5″, then when we look at the memory location of “a”, there will be a “5” stored there just as expected.

Reference type

  • You might be confused by all the different terminology used. However, class types, object types, and reference types all mean the exact same thing.
  • A variable of a reference type only stores the memory address of where the object is located. For example, “SomeClass anObject”, then when we look at “anObject” in memory, it just stores an address of another place in memory where all the details of “anObject” reside. This memory address is called a reference to the object.

 

 

System.nanoTime()

  • It will give you current time in nanoseconds(precise).
  • Usually used for measuring performance of the code.
  • To convert it to in seconds, divide it by 10^9 (1 sec = 1 nano second * 10 ^ 9)

Example…

long before = System.nanoTime();
//
// Some work goes to here
//
long after = System.nanoTime();

// Prints out time taken in nano seconds
System.out.println("Time taken: "+ (after-before) );  

Runnable vs. Thread

Difference

For both, you need to Override run() method to be created as a new thread by start() call.

thread runnable

implements Runnable (preferred way)

  • it shares the same object to multiple threads.
  • you can save a space for your class to extend any other class in future or now.

extends Thread

  • Each of your thread creates unique object and associate with it.
  • You can’t extend any other class which you required. (Java does not allow inheriting more than one class).

Runnable

  • You need to make Thread and put the ExampleThread in the parameter, and call .start()
public class ExampleThread implements Runnable{
   public void run(){
      System.out.println("Thread running");
   }
}

public class App{
   public static void main(String[] args){
      ExampleThread ex = new ExampleThread();
      Thread t = new Thread(ex);    // Runnable in Thread parameter
      t.start();
   }
}

thread

  • You can directly use .start(), because ExampleThread extends Thread
public class ExampleThread extends Thread{
   public void run(){
      System.out.println("Thread running");
   }
}

public class App{
   public static void main(String[] args){
      ExampleThread ex = new ExampleThread();
      ex.start();
   }
}

 

Types of Casting & instanceof

upcasting-downcasting

You must understand, that by casting you are not actually changing the object itself, you are just labeling it differently.

upcasting

  • Object of child class is assigned to reference varibale of parent type.
  • You do not need to upcast manually (implicit).
Manager x = new Manager();
Employee e = x;            // Doesn't need (Employee) before the x. 

downcasting

  • Object of parent class is assigned to reference varibale of child type.
  • You need to downcast manually which subtype to downcast (Explicit). Unless, compiler doesn’t know which subtype to downcast.
    • ex) Employee can downcast to either Manager or Clerk
Employee e = new Manager();
Manager x = (Manager) e;                // (Manager) is needed

 

  • If subtype is different, you will get ClassCastException.
  • To avoid the exception, you need to check which original subtype it was.
Employee e = new Clerk();
Manager x = (Manager) e;       // ClassCastException. 
                               // Original subtype is Clerk()

instanceof

  • You can use instanceof if casting is possible.
class Animal{}
class Dog extends Animal{
   static void cast(Animal a){
      Dog d = (Dog) a;              // Downcasting
   }

   public static void main(String[] args){
      Animal a1 = new Dog();
      if(a1 instanceof Dog){        // True
         Dog.cast(a1);              
      }
      
      Animal a2 = new Animal();
      if(a2 instanceof Dog){        // False
         Dog.cast(a2);              
      }
   }   
}