Saturday 11 January 2014

Advanced Java_ Multi-threading Part 11 - Deadlock




==
package Demo13;

/**
 * Title -- Advanced Java_ Multi-threading Part 11 - Deadlock
 *
 * @author Dharmaraj.Net
 */
public class App {

    public static void main(String[] args) throws Exception{
        final Runner runner = new Runner();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    runner.firstThread();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    runner.secondThread();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();
       
        runner.finished();
    }

}
============
package Demo13;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Runner {

    private Account acc1 = new Account();
    private Account acc2 = new Account();

    private Lock lock1 = new ReentrantLock();
    private Lock lock2 = new ReentrantLock();

    private void acquireLock(Lock firstLock, Lock secondLock) throws InterruptedException {
        while(true){
            //Acquire lock
            boolean getFirstLock = false;
            boolean getSecondLock = false;
           
           
            try {
                getFirstLock =  firstLock.tryLock();
                getSecondLock = secondLock.tryLock();
            } finally{
                if(getFirstLock && getSecondLock)
                {
                    return;
                }
               
                if(getFirstLock){
                    firstLock.unlock();
                }
                if(getSecondLock){
                    secondLock.unlock();
                }
            }
           
            //Locks not acquire
            Thread.sleep(1);
        }
    }

    public void firstThread() throws InterruptedException {
        Random random = new Random();

        for (int i = 0; i < 10000; i++) {
            acquireLock(lock1, lock2);
            lock2.lock();
            try {
                Account.transfer(acc1, acc2, random.nextInt(100));
            } finally {
                lock1.unlock();
                lock2.unlock();
            }
        }
    }

    public void secondThread() throws InterruptedException {
        Random random = new Random();

        for (int i = 0; i < 10000; i++) {
            acquireLock(lock2, lock1);
            try {
                Account.transfer(acc2, acc1, random.nextInt(100));
            } finally {
                lock1.unlock();
                lock2.unlock();
            }
        }
    }

    public void finished() {
        System.out.println("Account 1 Balance " + acc1.getBalance());
        System.out.println("Account 2 Balance " + acc2.getBalance());
        System.out.println("Total Balance "
                + (acc1.getBalance() + acc2.getBalance()));

    }
}
==========
package Demo13;

public class Account {
    private int balance = 10000;

    public void deposit(int amount) {
        balance += amount;
    }

    public void withdraw(int amount) {
        balance -= amount;
    }

    public static void transfer(Account acc1, Account acc2, int amount) {
        acc1.withdraw(amount);
        acc2.deposit(amount);
    }

    public int getBalance() {
        return balance;
    }
========

Advanced Java_ Multi-threading Part 10 - Re-entrant Locks


===
package Demo12;

import Demo11.Processor;

/**
 * Title -- Advanced Java_ Multi-threading Part 10 - Re-entrant Locks
 *
 * @author Dharmaraj.Net
 */
public class App {

    public static void main(String[] args) throws Exception{
        final Runner runner = new Runner();

        Thread t1 = new Thread(new Runnable() {

            public void run() {
                try {
                    runner.firstThread();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });

        Thread t2 = new Thread(new Runnable() {

            public void run() {
                try {
                    runner.secondThread();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();
       
        runner.finished();
    }

}
===========
package Demo12;

import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Runner {

    private int count = 0;
    // ReentrantLock Means once any thread hold the lock of ReentrantLock will
    // count how many time it take the lock and need to unlock the same time
    private Lock lock = new ReentrantLock();
    private Condition cond = lock.newCondition();

    private void increment() {
        for (int i = 0; i < 10000; i++) {
            count++;
        }
    }

    public void firstThread() throws InterruptedException {
        lock.lock();
        System.out.println("Waiting..");
        cond.await();
        System.out.println("Worken up..");
        try {
            increment();
        } finally {
            lock.unlock();
        }

    }

    public void secondThread() throws InterruptedException {
        Thread.sleep(1000);
        lock.lock();
        System.out.println("Press the return key...");
        new Scanner(System.in).nextLong();
        System.out.println("Got return key...");
        cond.signal();
        try {
            increment();
        } finally {
            lock.unlock();
        }
    }

    public void finished() {
        System.out.println("Count is " + count);
    }
}
=========
 

Advanced Java_ Multi-threading Part 8 - Wait and Notify


==
package Demo10;

/**
 * Title -- Advanced Java_ Multi-threading Part 8 - Wait and Notify
 * 
 * @author Dharmaraj.Net
 */
public class App {

 public static void main(String[] args) throws InterruptedException {
  final Processor processor = new Processor();

  Thread t1 = new Thread(new Runnable() {

   public void run() {
    try {
     processor.producer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }

  });

  Thread t2 = new Thread(new Runnable() {

   public void run() {
    try {
     processor.consumer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }

  });

  t1.start();
  t2.start();

  t1.join();
  t2.join();
 }

}
=====
package Demo10;

import java.util.Scanner;

public class Processor {
 public void producer() throws InterruptedException {
  synchronized (this) {
   System.out.println("Producer thread running ......");
   wait();
   System.out.println("Resumed ......");
  }
 }

 public void consumer() throws InterruptedException {
  Scanner scanner = new Scanner(System.in);
  Thread.sleep(2000);
  
  synchronized (this) {
   System.out.println("Waiting for return key");
   scanner.nextLine();
   System.out.println("Return key pressed");
   notify();
  }
 }
} 

Advanced Java_ Multi-threading Part 9 - A Worked Example Using Low-Level Synchronization


====
package Demo11;

/**
 * Title -- Advanced Java_ Multi-threading Part 9 - A Worked Example Using Low-Level Synchronization
 *
 * @author Dharmaraj.Net
 */
public class App {

 public static void main(String[] args) throws InterruptedException {
  final Processor processor = new Processor();

  Thread t1 = new Thread(new Runnable() {

   public void run() {
    try {
     processor.producer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }

  });

  Thread t2 = new Thread(new Runnable() {

   public void run() {
    try {
     processor.consumer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }

  });

  t1.start();
  t2.start();

  t1.join();
  t2.join();
 }

}
====
package Demo11;

import java.util.LinkedList;
import java.util.Random;

public class Processor {

 private LinkedList<Integer> list = new LinkedList<Integer>();
 private final int LIMIT = 10;
 private Object lock = new Object();

 /**
  * This method is add items to the list
  * 
  * @throws InterruptedException
  */
 public void producer() throws InterruptedException {
  int value = 0;
  while (true) {

   synchronized (lock) {

    while (list.size() == LIMIT) {
     lock.wait();
    }

    list.add(value++);
    lock.notify();
   }
  }

 }

 /**
  * This method is remove items to the list
  * 
  * @throws InterruptedException
  */
 public void consumer() throws InterruptedException {
  Random random = new Random();
  while (true) {
   synchronized (lock) {
    while (list.size() == 0) {
     lock.wait();
    }
    System.out.println("List Size " + list.size());
    int value = list.removeFirst();
    System.out.println("Value is " + value);
    lock.notify();
   }
   Thread.sleep(random.nextInt(1000));
  }
 }
} 

Advanced Java_ Multi-threading Part 6 -- Countdown Latches


==
package Demo8;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Title -- Advanced Java_ Multi-threading Part 6 -- Countdown Latches
 * 
 * @author Dharmaraj.Net
 */
public class App {

 public static void main(String[] args) {
  CountDownLatch latch = new CountDownLatch(3);
  ExecutorService executor = Executors.newFixedThreadPool(3);
  for (int i = 0; i < 3; i++) {
   executor.submit(new Processor(latch));
  }
  try {
   latch.await();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("Completed");
 }

}

class Processor implements Runnable {

 private CountDownLatch latch;

 public Processor(CountDownLatch latch) {
  this.latch = latch;
 }

 public void run() {
  System.out.println("Started....");
  
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  latch.countDown();
 }

}

Advanced Java_ Multi-threading Part 7 - Producer-Consumer


==
package Demo9;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
 * Title -- Advanced Java_ Multi-threading Part 7 - Producer-Consumer
 * 
 * @author Dharmaraj.Net
 */
public class App {
 private static BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);

 public static void main(String[] args) throws InterruptedException {
  Thread t1 = new Thread(new Runnable(){

   public void run() {
    try {
     producer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   
  });
  
  Thread t2 = new Thread(new Runnable(){

   public void run() {
    try {
     consumer();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   
  });
  
  t1.start();
  t2.start();
  
  t1.join();
  t2.join();
 }

 private static void producer() throws InterruptedException {
  Random random = new Random();

  while (true) {
   queue.put(random.nextInt(100));
  }
 }

 private static void consumer() throws InterruptedException {
  Random random = new Random();
  while (true) {
   Thread.sleep(100);

   if (random.nextInt(10) == 0) {
    Integer value = queue.take();

    System.out.println("Taken Value = " + value + "Queue Size is = "
      + queue.size());
   }
  }
 }
}
==== 

Advanced Java_ Multi-threading Part 5 -- Thread Pools


==
package Demo7;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Title -- Advanced Java_ Multi-threading Part 5 -- Thread Pools Note:--
 * 
 * @author Dharmaraj.Net
 */
public class App {
 public static void main(String[] args) {
  ExecutorService executor = Executors.newFixedThreadPool(2); // Two
                 // factor
                 // workers
                 // two
                 // threads
  for (int i = 0; i < 5; i++) {
   executor.submit(new processor(i));
  }
  executor.shutdown();
  System.out.println("All task submited");
  try {
   executor.awaitTermination(1, TimeUnit.DAYS);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  
  System.out.println("All task completed");
 }
}

class processor implements Runnable {

 private int id;

 public processor(int id) {
  this.id = id;
 }

 public void run() {
  System.out.println("Starting :" + id);
  try {
   Thread.sleep(5000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("Complet :" + id);
 }

}