• Tidak ada hasil yang ditemukan

Bab 27. Sinkronisasi Dengan Semafor

N/A
N/A
Protected

Academic year: 2021

Membagikan "Bab 27. Sinkronisasi Dengan Semafor"

Copied!
10
0
0

Teks penuh

(1)

Bab 27. Sinkronisasi Dengan Semafor

27.1. Pendahuluan

Sinkronisasi dua arah adalah suatu mekanisme dimana suatu thread dapat mengendalikan sinkronisasi thread lain, begitu pula sebaliknya. Berikut ini adalah sebuah program yang menggunakan proses sinkronisasi dua arah. Program yang dibuat dalam bahasa Java ini, bernama Hompimpah. Contoh program sinkronisasi dua arah adalah semafor berjenis non-spinlock. Semafor jenis non-spinlock mengimplementasikan kelas Semafor, dimana semafor yang digunakan adalah jika ada proses yang sedang berjalan, maka proses lain akan menunggu, sampai ada thread lain yang memanggilnya. Hal ini sesuai dengan prinsip critical section yaitu mutualy exclusive , hanya satu thread yang diizinkan mengakses critical section; progress, critical section pasti ada yang mengakses; bounded waiting, setiap thread dijamin dapat meng-akses critical section. Hal ini dapat dilihat dalam program yaitu ketika sang bandar sedang berada pada critical section, pemain akan menunggu hingga bandar selesai mengaksesnya. Sedangkan kebalikannya adalah semafor jenis spinlock , yang akan melakukan infinite loop , sehingga thread tersebut tidak ada jaminan akan masuk critical section . Semafor jenis non-spinlock ini terdiri dari 2 operasi untuk proses sinkronisasi, yaitu operasi buka(),dan operasi kunci() .

27.2. Penggunaan Semafor

Program ini berjalan layaknya permainan Hompimpah yang telah kita kenal. Adapun yang dilakukan dalam permainan hompimpah adalah sebagai berikut:

1. Peranan

Gambar 27.1. Peranan yang terdapat dalam permainan

Dalam permainan Hompimpah kita mengenal dua peranan, yaitu pemain-pemain yang melakukan hompimpah (gambar sebelah kanan yang berjumlah 5) dan seorang bandar (gambar sebelah kiri), yang berfungsi menetukan, kapan permainan dimulai dan kapan permainan berakhir. Dalam hal ini bandar bertindak sebagai pengatur jalannya permainan.

2. Memulai permainan

(2)

Permainan mulai ketika bandar menyerukan Hompimpah. Ketika itu bandar akan meminta pemain untuk melakukan hompimpah satu per satu(tidak serentak). Dalam program ini, pemain tidak gambreng secara bersamaan seperti gambreng pada umumnya, melainkan satu per satu dengan pengaturan dari Semafor.Kemudian bandar akan menyerukan gambreng sebagai penanda hompimpah berhenti, sehingga pemain pun menghentikan hompimpah dan masing-masing akan menunjukan tangannya, apakah telapak atau punggung.

3. Pengecekan pemenang

Gambar 27.3. Bandar memeriksa pemenang

Terlihat pada gambar, setelah bandar menyerukan gambreng dan hompimpah berhenti, bandar akan melakukan perhitungan banyaknya telapak dan punggung. Apabila bandar menemukan ada diantara telapak atau punggung yang berjumlah satu, maka satu-satunya pemain itu akan keluar sebagai pemenang. Namun apabila tidak ada diantara telapak atau punggung yang berjumlah satu, seperti pada gambar maka bandar akan mengulang permainan dengan menyerukan gambreng. Hal tersebut akan berulang terus-menerus hingga terdapat 1 tangan yang berbeda Dengan kata lain, bandar akan terus menyerukan gambreng dan mengulang permainan hingga menemukan pemenang.

Gambar 27.4. Bandar mengulang gambreng

Seperti halnya permainan Hompimpah yang diilustrasikan di atas, program Hompimpah juga berjalan demikian layaknya permainan Hompimpah sebenarnya. Tetapi, ada perbedaan terhadap jumlah bandarnya. Program Hompimpah memiliki jumlah bandar yang sama dengan jumlah pemainnya, sehingga setiap pemain memiliki satu bandar. Adapun tujuan sinkronisasi dua arah adalah mengendalikan thread-thread sesuai dengan keinginan kita melalui kendali bandarGambreng() yang diimplementasikan pada program Hompimpah.

27.3. Program

Contoh 27.1. Program yang menggunakan proses sinkronisasi dua arah

001 public class Hompimpah 002 {

003

004 private static final int JUMLAH_PEMAIN=6;

005 public static void main(String args[])throws Exception 006 {

007 Gambreng gamserver=new Gambreng(JUMLAH_PEMAIN); 008 Thread[] pemain=new Thread[JUMLAH_PEMAIN]; 009 for (int ii=0; ii<JUMLAH_PEMAIN; ii++) 010 {

(3)

011 pemain[ii]= new Thread (new Pemain(gamserver, ii)); 012 pemain[ii].start(); 013 014 } 015 gamserver.bandarGambreng(); 017 } 018 019 } 020

021 class Pemain implements Runnable 022 {

023 Pemain(Gambreng gserver, int nomer) 024 {

025 gamserver=gserver; 026 no_pemain=nomer; 027 }

028

029 public void run() 030 {

031 gamserver.pemainGambreng(no_pemain); 032 }

033

034 private Gambreng gamserver; 035 private int no_pemain; 036

037 } 038

039 class Gambreng 040 {

041 private boolean adaPemenang;

042 private int truePemain, trueCount, iterasiGambreng; 043 private int falsePemain, falseCount;

044 private int nomorPemenang, jumlahPemain; 045 private Semafor[] bandar, pemain;

046 private Semafor mutex; 047

048 public Gambreng(int jumlah) 049 {

050 bandar=new Semafor[jumlah]; 051 pemain=new Semafor[jumlah]; 052 for(int ii=0; ii<jumlah;ii++) 053 { 054 bandar[ii]=new Semafor(); 055 pemain[ii]=new Semafor(); 056 057 } 058 060 mutex=new Semafor(1); 061 jumlahPemain=jumlah; 062 iterasiGambreng=0; 063 resetGambreng(); 064 }

065 public void bandarGambreng() 066 { 067 syncBandar(); 068 while(!menangGambreng()) 069 { 070 resetGambreng(); 071 syncPemainBandar();

(4)

072 hitungGambreng(); 073 iterasiGambreng++; 074 }

075 syncPemain();

076 System.out.println("Nomor Peserta Pemain [0] - ["+

(jumlahPemain-1)+"] Pemenang Pemain nomor["+ nomorPemenang +"] Jumlah Iterasi["+ iterasiGambreng +"]");

077 }

078 public void pemainGambreng (int nomor) 079 { 080 syncBandarPemain(nomor); 081 while(!menangGambreng()) 082 { 083 mutex.kunci(); 084 085 if((int)(Math.random()*2)==1) 086 { 087 truePemain=nomor; 088 trueCount++; 089 090 } 091 else 092 { 093 falsePemain=nomor; 094 falseCount++; 095 } 096 mutex.buka(); 097 syncBandarPemain(nomor); 098 } 099 }

100 public void resetGambreng() 101 { 102 mutex.kunci(); 103 adaPemenang=false; 104 truePemain=0; 105 trueCount=0; 106 falsePemain=0; 107 falseCount=0; 108 109 mutex.buka(); 110 } 111

112 private boolean menangGambreng() 113 {

114 return adaPemenang; 115 }

116 private void hitungGambreng() 117 { 118 mutex.kunci(); 119 120 if(trueCount==1) 121 { 122 adaPemenang=true; 123 nomorPemenang=truePemain; 124 } 125 else if(falseCount==1) 126 { 127 adaPemenang=true; 128 nomorPemenang=falsePemain;

(5)

129 }

130 mutex.buka(); 131 }

132 private void syncPemainBandar() 133 {

134 for(int ii=0; ii<jumlahPemain;ii++) 135 { 136 pemain[ii].buka(); 137 bandar[ii].kunci(); 138 } 139 } 140

141 private void syncBandar() 142 { 143 for(int ii=0;ii<jumlahPemain;ii++) 144 { 145 bandar[ii].kunci(); 146 } 147 }

148 private void syncPemain() 149 { 150 for(int ii=0;ii<jumlahPemain;ii++) 151 { 152 pemain[ii].buka(); 153 } 154 }

155 private void syncBandarPemain(int ii) 156 { 157 bandar[ii].buka(); 158 pemain[ii].kunci(); 159 } 160 161 162 } 163 164 class Semafor 165 { 166 public Semafor() 167 { 168 value=0; 169 }

170 public Semafor(int val) 171 {

172 value=val; 173 }

174 public synchronized void kunci() 175 { 176 while(value==0) 177 { 178 try 179 { 180 wait(); 181 182 } 183 catch(InterruptedException e) 184 { 185 } 186 value--; 187 }

(6)

188 189 }

190 public synchronized void buka() 191 {

192 value++; 193 notify(); 194 }

195 private int value; 196 }

27.4. Penjelasan Program

Program Hompimpah terdiri dari 4 class yaitu class Hompimpah, class Pemain, class Gambreng,class Semafor. Masing-masing class berfungsi sebagai berikut:

1. Class Hompimpah: dalam kelas ini program Hompimpah dapat dijalankan

2. Class Gambreng: dalam kelas ini seluruh proses permainan Hompimpah dijalankan. 3. Class Semafor: kelas ini menjalankan proses sinkronisasi.

4. Class Hompimpah: dalam kelas terdapat fungsi run() dengan fungsi ini tiap-tiap pemain akan dihidupkan.

Penjelasan selengkapnya sebagai berikut:

Contoh 27.2. Class Hompimpah

001 public class Hompimpah 002 {

003

004 private static final int JUMLAH_PEMAIN=6;

005 public static void main(String args[])throws Exception 006 {

007 Gambreng gamserver=new Gambreng(JUMLAH_PEMAIN); 008 Thread[] pemain=new Thread[JUMLAH_PEMAIN]; 009 for (int ii=0; ii<JUMLAH_PEMAIN; ii++) 010 {

011 pemain[ii]= new Thread (new Pemain(gamserver, ii)); 012 pemain[ii].start(); 013 014 } 015 gamserver.bandarGambreng(); 017 } 018 019 } 020

Pada class Hompimpah, dibuat objek baru dari class Gambreng (baris 7), dimana dalam kelas tersebut dibuat 2 jenis thread yaitu thread bandar dan thread pemain. Masing-masing thread adalah array dari objek Semafor, yang berkapasitas JUMLAH_PEMAIN, yaitu 6. Kemudian kedua jenis thread di set value-nya sebagai 0 (terdapat pada

class Gambreng). Hal ini mengindikasikan bahwa thread bandar dan pemain sedang tidur. Dalam kelas Gambreng,

mutex sebagai objek dari class Semafor, di set 1,yang berarti bahwa critical section sedang dalam keadaan

available atau tidak ada thread yang sedang memakai. Kemudian iterasiGambreng di set 0 dan pemanggilan method resetGambreng() pada class Gambreng sebagai penanda awal permainan Pada baris ke 8 class

Hompimpah dibuat array object baru dari class Thread yaitu pemain sebanyak JUMLAH_PEMAIN yang di set 6. Tiap-tiap thread memiliki no_pemain dan memiliki objek dari class Gambreng. Selanjutnya thread- thread

tersebut menjalankan method run()-nya, dimana dalam method tersebut tiap-tiap thread pemain mengirimkan

(7)

Contoh 27.3. method pemainGambreng

078 public void pemainGambreng (int nomor) 079 { 080 syncBandarPemain(nomor); 081 while(!menangGambreng()) 082 { 083 mutex.kunci(); 084 085 if((int)(Math.random()*2)==1) 086 { 087 truePemain=nomor; 088 trueCount++; 089 090 } 091 else 092 { 093 falsePemain=nomor; 094 falseCount++; 095 } 096 mutex.buka(); 097 syncBandarPemain(nomor); 098 } 099 }

100 public void resetGambreng() 101 { 102 mutex.kunci(); 103 adaPemenang=false; 104 truePemain=0; 105 trueCount=0; 106 falsePemain=0; 107 falseCount=0; 108 109 mutex.buka(); 110 } 111

Pada fungsi tersebut tiap-tiap thread akan mengakses critical section secara bergantian, sesuai dengan prinsip

mutual exclusion . Di dalam critical section , thread-thread akan dicek apakah truePemain(telapak) atau

falsePemain(punggung) kemudian dihitung berapa jumlah telapak dan punggungnya. Proses ini akan terus me-loop sampai ada pemenang. Sebelum memasuki critical section dan melakukan pengecekan, sistem melakukan proses sinkronisasi bandar dan pemain, dengan memangil fungsi syncBandarPemain()

Contoh 27.4. syncBandarPemain

155 private void syncBandarPemain(int ii) 156 {

157 bandar[ii].buka(); 158 pemain[ii].kunci(); 159 }

160

dalam fungsi tersebut bandar melepaskan kunci, dan memanggil thread pemain dengan notify() yang

merupakan bagian dari fungsi buka() dari class Semafor, untuk kemudian thread tersebut dapat mengakses

critical section. Setelah seluruh thread pemain mengakses critical section dan melakukan pengecekan, program

memanggil fungsi bandarGambreng() pada class Gambreng,untuk melakukan proses sinkronisasi bandar

(8)

Contoh 27.5. syncBandar

141 private void syncBandar() 142 { 143 for(int ii=0;ii<jumlahPemain;ii++) 144 { 145 bandar[ii].kunci(); 146 } 147 }

, sehingga bandar terkunci dalam critical section dan memegang kekuasaan dalam Gambreng untuk melakukan perulangan fungsi-fungsi berikut, yang masing-masing akan dipanggil dalam fungsi bandarGambreng() :

1. Me-reset permainan gambreng dengan memanggil fungsi resetGambreng().

Contoh 27.6. resetGambreng

100 public void resetGambreng() 101 { 102 mutex.kunci(); 103 adaPemenang=false; 104 truePemain=0; 105 trueCount=0; 106 falsePemain=0; 107 falseCount=0; 108 109 mutex.buka(); 110 } 111

Dalam fungsi resetGambreng(), truePemain, falsePemain, trueCount dan falseCount = 0,

kemudian ada pemenang diset false, sebagai tanda awal dari permainan.

2. Melakukan sinkronisasi pemain dan bandar dengan memanggil fungsi syncPemainBandar().

Contoh 27.7. syncPemainBandar

132 private void syncPemainBandar() 133 {

134 for(int ii=0; ii<jumlahPemain;ii++) 135 {

136 pemain[ii].buka(); 137 bandar[ii].kunci(); 138 }

139 }

Ketika melakukan pemanggilan fungsi ini, seluruh pemain dibangunkan kemudian tiap-tiap bandar akan tidur. Dengan fungsi ini, bandar akan tetap menunggu sampai semua pemain membangunkannya. Dan ketika bandar bangun, pemain akan ditidurkan kembali.

3. Melakukan penghitungan dengan fungsi hitungGambreng()

Contoh 27.8. hitungGambreng

116 private void hitungGambreng() 117 {

118 mutex.kunci(); 119

120 if(trueCount==1) 121 {

(9)

122 adaPemenang=true; 123 nomorPemenang=truePemain; 124 } 125 else if(falseCount == 1) 126 { 127 adaPemenang=true; 128 nomorPemenang=falsePemain; 129 } 130 mutex.buka(); 131 }

Dengan fungsi ini, kembali melakukan pengaksesan variable. Dengan melakukan pengecekan, apabila salah satu diantara trueCount atau falseCount bernilai 1, maka adaPemenang. Nilai ini akan diproses oleh fungsi

menangGambreng(), yang akan mengembalikan nilai boolean(true atau false). Jika fungsi tersebut bernilai true

maka proses loop berhenti.

4. Menghitung iterasi perulangan, sampai fungsi menangGambreng() mengembalikan nilai true, yang

menandakan adanya pemenang.

Saat proses perulangan berhenti, pemain melepaskan kunci kemudian sistem menampilkan output saat execute, berupa no_pemain yang keluar sebagai pemenang. Setiap proses execute akan menampilkan nomor pemain

yang berbeda-beda , karena proses random dan urutan pengaksesan critical section oleh thread pada tiap peng-

execute-an berbeda-beda.

Contoh 27.9. Keluaran Program

Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[3] Jumlah Iterasi[12] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[2] Jumlah Iterasi[1] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[0] Jumlah Iterasi[6] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[4] Jumlah Iterasi[2] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[1] Jumlah Iterasi[14] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[3] Jumlah Iterasi[9] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[5] Jumlah Iterasi[3] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[3] Jumlah Iterasi[2] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[4] Jumlah Iterasi[5] Nomor Peserta Pemain [0] - [5] Pemenang Pemain nomor[0] Jumlah Iterasi[11]

Contoh di atas menunjukkan hasil Hompimpah tidak selalu sama. Jumlah iterasi menunjukkan berapa kali bandar menyerukan gambreng dan mengulang permainan.

27.5. Rangkuman

Program Hompimpah merupakan ilustrasi dimana sebuah thread memegang kendali sinkronisasi thread lainnya. Seperti yang dijelaskan dalam program masing-masing dari pemain saling mengendalikan satu sama lain, dengan menggunakan alat sinkronisasi yang bernama semafor. Semafor dalam program adalah semafor buatan berupa class Semafor yang dibuat dalam bahasa Java. Adapun di dalamnya terdapat 2 fungsi yaitu fungsi buka() dan fungsi kunci() dengan

fungsi-fungsi inilah masing-masing thread dapat mengendalikan satu sama lain

Rujukan

[Silberschatz2005] Avi Silberschatz, Peter Galvin, dan Grag Gagne. 2005. Operating Systems

(10)

Appendix

27.6. Penjelasan Alur Program

1. Mula - mula semua bandar dan pemain tidur

2. Dibuat thread Pemain sebanyak JUMLAH_PEMAIN yang kemudian akan menjalankan run() secara terpisah. 3. Setiap thread Pemain yang memanggil pemainGambreng akan terhambat pada method syncBandarPemain(nomor), ketika semua pemain sudah menjalankan method ini, semua bandar dalam keadaan bangun(buka).

4. bandarGambreng (baris 15) dijalankan

5. Karena syncPemainBandar() dijalankan maka thread Pemain yang tadinya terhambat dapat jalan.

6. Setelah semua Pemain sudah gambreng (yang kemudian akan terhambat di syncBandarPemain(nomor) di bawah), maka akan hitungGambreng().

7. Jika !MenangGambreng, Pemain akan di buka lagi.

Gambar

Gambar 27.2. Bandar memulai permainan
Gambar 27.3. Bandar memeriksa pemenang

Referensi

Dokumen terkait

Setelah rancang bangun alat selesai, dilakukan pengujian mesin tersebut dan dicatat hasil pengujiannya sesuai atau tidak dengan gambar perencanaan, perencanaan

Pemimpin: Kami menyembah Dikau ya Tuhan dan bersyukur kepada-Mu Umat: Sebab dengan Salib Suci-Mu Engkau telah menebus

Gardner (1986), dikutip dari swanburg (2001) mendefinisikan kepemimpinan sebagai “suatu proses persuasi dn memberikan contoh sehingga individu (atau pimpinan kelompok)

Berdasarkan temuan penelitian yang telah diuraikan pada bagian pembahasan, maka secara umum dapat disimpulkan bahwa MGMP PKn SMP pengembangan kompetensi pedagogik

Pendek kata, Presiden DK PBB, ASEAN memiliki dorongan yang kuat untuk menjamin bahwa kesulitan yang saat ini dihadapi kedua Negara anggotanya dapat diselesaikan dengan cara-cara

Urut Anggota Rumah Tangga (B4R1) File: sn80_t21 Tipe: Diskrit Format: numeric Desimal: 0 Range: 1-3. Pertanyaan

Ini sangkaan yang tidak benar (Blanchard dan Thacker:2004). Jika rasio kurang dari 100 persen, dari biaya program lebih dari itu kembali ke organisasi. Program-program tersebut perlu

Digunakan untuk melindungi tangan dan bagian lainnya dari dari benda tajam atau goresan, bahan kimia, benda panas dan dingin, kontak dengan arus listrik. Sarung