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();
}

2 komentar:

  1. nice, a tutorial about thread, aku komen ya :)

    berhubung wait() dan notify() ini adalah method object maka sebelum menginvoke salah satu method di atas kita harus mendapatkan lock dari object tersebut. hal ini beda dengan method sleep(), yield() atau join() yg notabene adalah static method dari class java.lang.Thread. coba aja ilangin blok synchronized dari source diatas, ketika di run pasti akan muncul turunan dari RuntimeException :)

    salah satu keistimewaan lagi dari method wait() adalah methid ini melepas lock dari object tersebut sedangkan method2 yg lain akan tetep keep locknya

    sementara gitu aja deh ton :)

    BalasHapus
  2. the gandos : nice comment gan.. tambahan dikit biar lebih jelas : IllegalStateException muncul karena object yg meng-invoke method notify() tidak memiliki akses ekslusif terhadap thread...

    BalasHapus