Minggu, 21 November 2010

Thread : How to wait() and notify()

Sebuah Thread dapat dihentikan sementara waktu dan memberika kesempatan pada thread yang lain untuk dieksekusi. Thread yang lain dapat men-notify agar thread dengan status 'wait' dapat dijalankan kembali prosesnya.

Berikut contoh penggunaan method wait() dan notify...

Terdapat 3 class masing-masing berfungsi untuk mengenerate Bilangan Ganjil, Genap dan Bulat. Thread Generator Bilangan Genap dan Bulat  akan berhenti jika telah mencapai batas angka tertentu sampai Ketika diakhir proses Generator Bilangan Ganjil akan me-notify Thread Generator Bilangan Bulat dan Genap untuk kembali melanjutkan prosesnya.

public class GeneratorBilanganBulat extends Thread{
 private int maxNumber = 0;
 private double sleepSec = 0;
 private int waitAt ;
 
 public volatile boolean finished = false;
 
 public GeneratorBilanganBulat(int max, double miliSecSleep, int waitAt) {
  maxNumber = max;
  sleepSec = miliSecSleep;
  waitAt = waitAt;
 }

 public void run() {
  try {
   int evenSeq = 1;
   for (int i = 0; i <= maxNumber; i++) {
    System.out.println("BULAT (" + evenSeq++ +") : " + i);
    if(i == waitAt) { 
     synchronized(this) {
      wait();
     }
    }
    sleep((long) (sleepSec*1000));
   }
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}
public class GeneratorBilanganGenap extends Thread{
 private int maxNumber = 0;
 private double sleepSec = 0;
 private int waitFor;
 
 public GeneratorBilanganGenap(int max, double miliSecSleep, int waitFor) {
  maxNumber = max;
  sleepSec = miliSecSleep;
  this.waitFor = waitFor;
 }

 public void run() {
  try {
   int seq = 1;
   for (int i = 0; i <= maxNumber; i++) {
    if(i%2 == 0) {
     System.out.println("GENAP (" + seq++ +") : " + i);
     
     if (i == waitFor) {
      synchronized(this) {
       wait();
      }
     }
     // hentikan proses utk jangka waktu tertentu 
     // jika telah menemukan bilangan genap
     sleep((long) (sleepSec*1000));
    }
   }
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 } 
}

public class GeneratorBilanganGanjil extends Thread{
 private int maxNumber = 0;
 private double sleepSec = 0;
 private GeneratorBilanganGenap genapThread;
 private GeneratorBilanganBulat bulatThread;
 
 public GeneratorBilanganGanjil(int max, double miliSecSleep, 
           GeneratorBilanganGenap genapThread, GeneratorBilanganBulat bulatThread) {
  maxNumber = max;
  sleepSec = miliSecSleep;
  this.genapThread = genapThread;
  this.bulatThread = bulatThread;
 } 
 
 public void run() {
  try {
   int evenSeq = 1;
   for (int i = 0; i <= maxNumber; i++) {
    if(i%2 == 1) System.out.println("GANJIL (" + evenSeq++ +") : " + i);
    
    sleep((long) (sleepSec*1000));
    
   }
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
    
  synchronized(genapThread ) {
   System.out.println("Ganjil sudah selesai lanjutkan dengan yg Genap");
   genapThread.notify();
  }
  synchronized(bulatThread ) {
   System.out.println("Ganjil sudah selesai lanjutkan dengan yg Bulat");
   bulatThread.notify();
  }
 }
}

public class ThreadTest {
 public static void main(String[] args) throws InterruptedException {
  GeneratorBilanganGenap genapThread = new GeneratorBilanganGenap(30, 0.2, 10);
  GeneratorBilanganBulat bulatThread = new GeneratorBilanganBulat(30, 0.2, 20);
  GeneratorBilanganGanjil ganjilThread = new GeneratorBilanganGanjil(30, 0.2, genapThread, bulatThread);
  genapThread.start(); 
  bulatThread.start();
  ganjilThread.start();  
 }
}
untuk dapat menjalankan fungsi wait dan notify maka bentuk umumnya adalah sbb:
synchronized (someObject) {
    someObject.wait();
}

/* different thread / object */
synchronized (someObject) {
    someObject.notify();
}

Perkenalan Thread

Thread merupakan satuan kecil dari proses dalam pemograman Java. Dengan meng-extends Thread atau meng-implements Runnable maka sebuah Class dapat menjadi sebuah Proses yg bisa dieksekusi secara bersamaan dengan Main Thread (Thread utama yang terdapat pada class yg memiliki public static void Main(...) ketika meluncurkan program pertama kali).
Thread digunakan untuk melakukan instruksi khusus yang waktu eksekusinya dapat berbarengan dengan Main Thread.

Statement yang akan dijalankan oleh oleh sebuah Thread di tempatkan pada method run().

public class GeneratorBilanganGenap extends Thread{
 private int maxNumber = 0;
 private double sleepSec = 0;
 private String name;
 
 public GeneratorBilanganGenap(String name, int max, double miliSecSleep) {
  this.name = name;
  maxNumber = max;
  sleepSec = miliSecSleep;
 }

 public void run() {
  try {
   int seq = 1;
   for (int i = 0; i <= maxNumber; i++) {
    if(i%2 == 0) {
     System.out.println("Name : " + name + ", urutan(" + seq++ +") : " + i);
     
     // hentikan proses utk jangka waktu tertentu 
     // jika telah menemukan bilangan genap
     sleep((long) (sleepSec*1000));
    }
   }
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  // create thread masukan parameter constructor 
  GeneratorBilanganGenap generator1 = new GeneratorBilanganGenap("T1", 20, 0.2);
  GeneratorBilanganGenap generator2 = new GeneratorBilanganGenap("T2", 40, 0.2);
  
  // mulai jalankan thread / proses
  generator1.start();
  generator2.start();
 }
}


Dengan meng-create object Thread tidak serta merta akan menjalankan statement pada method Run(). Agar tereksekusi harus menjalankan method start() pada Thread tersebut.

Catatan : method sleep(long miliseconds), berguna untuk menghentikan proses yg dijalankan thread tersebut dalam jangka waktu tertentu dalam hitungan milisecond.