Penjelasan Program

Program ini meng- import package java.util untuk mengambil Date yang akan kita gunakan sebagai data yang dipertukarkan proses konsumen dan produsen melalui buffer (baris 006).

Contoh 25.2 MasalahProdusenKonsumen

      
008   public class MasalahProdusenKonsumen
009  {
010      public static void main(String args[])
011     {
012         BoundedBuffer server = new BoundedBuffer();
013         Produsen threadProdusen = new Produsen(server);
014         Konsumen threadKonsumen = new Konsumen(server);
015         threadProdusen.start();
016         threadKonsumen.start();
017      }
018   }

Kelas MasalahProdusenKonsumen mengandung method main yang membuat instansiasi objek BoundedBuffer yang diberi nama server. Server merupakan antrian sementara yang akan digunakan oleh produsen dan konsumen untuk menaruh data yang dipertukarkan.

Contoh 25.3 BoundedBuffer

      
029      public BoundedBuffer()
030      {
031         count=tmptMsk=tmptKlr=0;
032         buffer=new Object[UK_BUFFER];
033         mutex=new Semaphore(1);
034         tempat_kosong=new Semaphore(UK_BUFFER);
035         tempat_terisi=new Semaphore(0);
036      }      

Selain itu MasalahProdusenKonsumen akan membuat instansiasi dari kelas Produsen dan Konsumen, yang masing-masing berjalan sebagai thread yang paralel dengan main. Ketika thread produsen dan konsumen dimulai di main dengan dipanggilnya fungsi start()(baris 015 dan 016), masing-masing proses itu akan menjalankan method run()-nya seperti di bawah ini.

Contoh 25.4 Method Run Konsumen

      
072      public void run()
073      {
074         Date data;
075         while(true)
076         {
077             BoundedBuffer.napping();
078             System.out.println("Konsumen ingin mengambil.");
079             data = (Date) buffer.ambil();
080         }
081      }

Contoh 25.5 Method Run Produsen

      
091      public void run()
092      {
093          Date data;
094          while(true)
095          {
096              data=new Date();
097              BoundedBuffer.napping();
098              System.out.println("Produsen menghasilkan :  "+data);
099              System.out.println("Produsen ingin menaruh.");
100              buffer.taruh(data);
101          }
102      }

Dapat dilihat bahwa masing-masing thread akan tidur sejenak dengan fungsi napping()(baris 077 dan baris 097), untuk memberi jeda antar proses. Waktu untuk tidur ini adalah angka random yang dihasilkan dari Math.random()(baris 039).

Contoh 25.6 Napping

      
037      public static void napping()
038      {
039         int tidur = (int) (TIDUR*Math.random());
040         try{ Thread.sleep(tidur*1000);}
041            catch(InterruptedException e){}
042      }

Dalam fungsi napping(), program akan menangkap jika ada InterruptedException(baris 040-041). Perlu diingat bahwa program ini tidak akan terminasi sendiri (akan terjadi loop yang terus-menerus). Dengan demikan, kita harus menterminasi program ini dengan paksa (dengan perintah CTRL+C), akan ditangkap di bagian catch ini, sehingga program akan diterminasi.

Fungsi lain yang dipanggil pada saat thread produsen dan konsumen menjalankan run() adalah taruh yang dipanggil oleh produsen dan ambil yang dipanggil oleh konsumen. taruh berfungsi untuk memasukkan data ke dalam buffer sedangkan ambil untuk mengambil data.

Contoh 25.7 Taruh dan Ambil

      
043      public void taruh(Object item)
044      {
045         tempat_kosong.acquire();   mutex.acquire();
046         ++count;
047         buffer[tmptMsk]=item;
048         tmptMsk=(tmptMsk+1)% UK_BUFFER;
049         System.out.println("Produsen memasukkan :   "+item);
050         mutex.release();   tempat_terisi.release();
051      }
052      public Object ambil()
053      {
054         Object item;
055         tempat_terisi.acquire();   mutex.acquire();
056         --count;
057         item=buffer[tmptKlr];
058         tmptKlr=(tmptKlr+1)%UK_BUFFER;
059         System.out.println("Konsumen mengambil :  "+item);
060         mutex.release(); tempat_kosong.release();
061         return item;
062      }

Pada kelas BoundedBuffer tadi, telah diinstansiasikan 3 buah semafor yang diinisialisasi dengan nilai 1 untuk mutex, ukuran buffer untuk tempat_kosong, dan 0 untuk tempat_terisi. Semafor ini digunakan pada saat percobaan memasukkan atau mengambil data dari buffer oleh thread produsen dan konsumen.

Contoh 25.8 Instansiasi dan Inisialisasi Semafor

      
024      private Semaphore mutex;                
025      private Semaphore tempat_kosong;
026      private Semaphore tempat_terisi;   
.
.
.
033      mutex=new Semaphore(1);
034      tempat_kosong=new Semaphore(UK_BUFFER);
035      tempat_terisi=new Semaphore(0);

Dengan demikian, pada saat produsen memanggil taruh, hal pertama yang dilakukan adalah percobaan mengurangi jumlah tempat kosong melalui acquire semafor tempat_kosong (baris 045). Hal ini diikuti oleh percobaan pengambilalihan mutex. (baris 045). Sedangkan konsumen mencoba mengurangi jumlah tempat terisi melalui pengambilalihan semafor tempat_terisi (baris 055). Setelah itu konsumen berusaha mengambil alih juga semafor mutex(baris 055). Setelah produsen berhasil memperoleh mutex dan mengurangi tempat_kosong, maka ia akan mengeksekusikan baris 046-049 dari program taruh yang merupakan critical section. Ketika selesai, ia akan melepas kembali mutex dan mengupdate jumlah tempat terisi dengan cara melepas semafor tempat_terisi. Demikian pula dengan konsumen, setelah memperoleh semafor mutex dan tempat_terisi, akan mengeksekusi baris 056-059 dari program ambil(yang juga merupakan critical section), lalu melepas kembali mutex dan mengupdate jumlah tempat kosong dengan melepas semafor tempat_kosong.

Contoh 25.9 Acquire Semafor

        
111   public synchronized void acquire()
112   {
113      while(value==0)
114      {
115         try{wait();}
116         catch(InterruptedException e){}
117      }
118      value--;
119   }

Contoh 25.10 Release Semafor

        
120   public synchronized void release()
121   {
122      ++value;
123      notify();
124   }

Semafor mutex bernilai 1 untuk menandai bahwa buffer sedang dipakai oleh sebuah proses. Ketika diinisialisasi pun ia bernilai 1, yang artinya di keadaan awal buffer tidak dipakai oleh proses manapun. Ketika sebuah proses berusaha meng- acquire semafor ini, dan menemui bahwa keadaannya sedang bernilai 0 (baris 113) yang berarti buffer sedang dipakai proses lain, maka ia akan menunggu (baris 115) dengan fungsi wait() sampai nilai mutex bernilai 1 ( buffer bebas). Ketika sebuah proses selesai, ia akan me- release mutex dengan menjadikan nilainya kembali ke 1. (baris 122) dan memberitahu proses lain yang sedang menunggu dengan memanggil notify()(baris 123).

Semafor tempat_kosong adalah jumlah tempat kosong. Dengan demikian ketika di- acquire oleh produsen, jika bernilai 0 ( buffer penuh), maka produsen akan menunggu (baris 115), karena jika penuh maka produsen tidak bisa menimpa data yang tersimpan. Jika tidak 0, maka produsen akan mengurangi nilainya (mengurangi jumlah tempat yang kosong). Setelah produsen selesai maka ia akan mengubah nilai tempat_terisi (menambahkan 1 tempat yang terisi) dengan me- release semafor tempat_terisi. Untuk konsumen sama saja, namun yang di- acquire adalah tempat_terisi (jika tempat_terisi=0 berarti buffer kosong, belum ada yang terisi) dan yang di- release ketika proses selesai adalah tempat_kosong.

Dengan demikian, produsen dan konsumen akan secara bergantian menaruh atau mengambil data dari buffer, dan produsen tidak akan menaruh data jika buffer penuh (tidak akan menimpa data yang sudah ada), dan konsumen tidak bisa pula mengambil data jika buffer kosong.

Salah satu contoh keluaran program ini adalah:

Contoh 25.11 Contoh keluaran

        
Konsumen ingin mengambil.
Produsen menghasilkan :  Tue Apr 10 16:12:16 ICT 2007
Produsen ingin menaruh.
Produsen memasukkan :   Tue Apr 10 16:12:16 ICT 2007
Konsumen mengambil :  Tue Apr 10 16:12:16 ICT 2007
Produsen menghasilkan :  Tue Apr 10 16:12:19 ICT 2007
Produsen ingin menaruh.
Produsen memasukkan :   Tue Apr 10 16:12:19 ICT 2007
Konsumen ingin mengambil.
Konsumen mengambil :  Tue Apr 10 16:12:19 ICT 2007
Produsen menghasilkan :  Tue Apr 10 16:12:20 ICT 2007
Konsumen ingin mengambil.
Produsen ingin menaruh.
Produsen memasukkan :   Tue Apr 10 16:12:20 ICT 2007
Konsumen mengambil :  Tue Apr 10 16:12:20 ICT 2007
Konsumen ingin mengambil.
Produsen menghasilkan :  Tue Apr 10 16:12:22 ICT 2007
Produsen ingin menaruh.
Produsen memasukkan :   Tue Apr 10 16:12:22 ICT 2007
Konsumen mengambil :  Tue Apr 10 16:12:22 ICT 2007