• Tidak ada hasil yang ditemukan

PEMROGRAMAN BERORIENTASI OBJEK. Sinkronisasi

N/A
N/A
Protected

Academic year: 2021

Membagikan "PEMROGRAMAN BERORIENTASI OBJEK. Sinkronisasi"

Copied!
13
0
0

Teks penuh

(1)

PEMROGRAMAN BERORIENTASI OBJEK

“ Sinkronisasi ”

Oleh : Farhat, ST, MMSI, MSc

(2)

SINKRONISASI

Sinkronisasi adalah suatu proses pengendalian akses dari sumber daya terbagi pakai (shared resource) oleh banyak thread sedemikian sehingga hanya satu thread yang dapat mengakses sumber daya tertentu pada satu waktu.

Dalam aplikasi multithreaded yang tidak tersinkronisasi, sangat mungkin terjadi adanya satu thread memodifikasi suatu obyek yang dipakai bersama pada saat thread lain sedangkan dalam proses menggunakan atau mengupdate nilai obyek tersebut. Sinkronisasi mencegah jenis kerusakan data demikian, jika tidak disinkronkan maka dapat mengakibatkan pembacaan yang buruk dan error yang signifikan. Secara umum bagian kritis (critical sections) dari kode biasanya ditandai dengan kata kunci synchronized.

Jadi sinkronisasi itu ialah suatu proses pengendalian untuk salah satu thread dari banyak thread untuk dapat mengakses sumber daya tertentu pada satu waktu.

Sinkronisasi merupakan mekanisme untuk mengontrol eksekusi dari thread-thread berbeda sehingga ketika banyak thread mengakses variabel “shared”, dapat dipastikan eksekusinya benar. Java punya keyword synchronized – dapat digunakan untuk memperkenalkan suatu segmen kode atau metode yang akan dapat diakses hanya oleh suatu thread tunggal pada satu waktu.

Sebelum memasuki wilayah sinkronisasi, suatu thread akan memperoleh semaphore yang berasosiasi dengan wilayah tersebut – jika telah diambil oleh thread lain, maka thread tersebut mem-blokir (menunggu) sampai semaphore dilepas.

Dalam Java, obyek dengan satu atau lebih metode synchronized disebut sebagai monitor. Ketika thread memanggil metode synchronized, hanya satu thread yang dibolehkan pada satu waktu, lainnya menunggu dalam antrian (queue). Dalam aplikasi jenis producer- consumer, thread consumer mungkin mendapatkan tidak ada cukup elemen untuk dikonsumsi. Tanggung jawab monitor untuk memastikan bahwa thread-thread yang menunggu producer diberitahu segera setelah elemen-elemen diproduksi.

Suatu lock (kunci) digunakan untuk mengsinkronkan akses ke sumber daya terbagi-pakai. Suatu lock dapat diasosiasikan dengan suatu sumber daya terbagi-pakai. Thread memperoleh akses ke sumber daya terbagi-pakai dengan terlebih dahulu mendapatkan lock yang terasosiasi dengan obyek atau block dari kode. Pada suatu waktu yang diberikan, harus hanya satu thread yang dapat memegang lock dan dengan cara demikian mempunyai akses ke sumber daya terbagi-pakai. Lock seperti ini mengimplementasikan mutual exclusion.

(3)

 Suatu thread harus memperoleh object lock yang diasosiasikan dengan suatu sumber daya terbagi-pakai, sebelum ia dapat memasuki sumber daya terbagi-pakai tersebut. Sistem runtime memastikan bahwa tidak ada thread lain yang dapat memasuki sumber daya terbagi-pakai jika suatu thread sudah memegang (hold) object lock yang diaosiasikan dengan sumber daya terbagi-pakai tersebut. Jika suatu thread tidak dapat dengan segera mendapatkan object lock,maka ia harus menunggu sampai lock tersedia.  Pada saat suatu thread berada di dalam suatu sumber daya berbagi-pakai, sistem

runtime memastikan bahwa object lock juga dilepaskan. Jika suatu thread lain sedang menunggu object lock ini, ia dapat diproses untuk mendapatkan lock agar memperoleh akses ke sumber daya terbagi-pakai tersebut.

Kelas juga mempunyai suatu lock spesifik kelas yang bersifat analog dengan object lock. Lock demikian sesungguhnya merupakan lock pada obyek java.lang.Class yang berasosiasi dengan kelas tersebut. Diberikan suatu kelas A, referensi A.kelas menyatakan obyek kelas unik ini. Class lock tersebut digunakan dengan cara yang sama seperti object lock untuk mengimplementasikan mutual exclusion.

Terdapat 2 (dua) bagian kode yang dapat dikenakan sinkronisasi di dalam Java: • Synchronized method

Synchronized statement sama dengan synchronized method. Synchronized statement hanya dapat dieksekusi setelah suatu thread memperoleh lock terhadap obyek atau kelas yang dirujuk dalam pernyataan tersinkronisasi (synchronized statement).

• Synchronized block

- Upaya agar kode tertentu dijalankan secara berurutan dengan jaminan kode tersebut tidak akan dijalankan oleh yang lain dalam waktu bersamaan.

- Jika sinkronisasi diterapkan dalam metode, dipastikan bahwa seluruh kode di dalam metode tersebut dijalankan tanpa diinterupsi oleh yang lain.

Contoh:

// nama file : TesSinkron.java public class TesSinkron {

public static void main (String [] args) { Mobil m1 = new Mobil("M-1");

Mobil m2 = new Mobil("M-2"); m1.start();

m2.start(); } }

class Mobil extends Thread { // konstruktor

(4)

super (id); }

// Mendefinisikan sendiri run() public void run() {

String nama = getName(); SinkronisasiKeluaran.info(nama);

} }

class SinkronisasiKeluaran {

public static synchronized void info(String nama){ for (int i=0; i<5; i++) {

try { Thread.sleep(1000); } catch(InterruptedException ie) { System.out.println("Terinterupsi"); }

System.out.println("Thread " + nama + ":Posisi" + i ); } } }

Komunikasi Antar Thread

Thread adalah rangkaian eksekusi dari sebuah aplikasi java dan setiap program java minimal memiliki satu buah thread. Sebuah thread bisa berada di salah satu dari 4 status, yaitu new, runnable, blocked, dan dead.

(5)

 New, Thread yang berada di status ini adalah objek dari kelas Thread yang baru dibuat, yaitu saat instansiasi objek dengan statement new. Saat thread berada di status new,belum ada sumber daya yang dialokasikan, sehingga thread belum bisa menjalankan perintah apapun.

 Runnable. Agar thread bisa menjalankan tugasnya, method start() dari kelas Thread harus dipanggil. Ada dua hal yang terjadi saat pemanggilan method start(), yaitu alokasi memori untuk thread yang dibuat dan pemanggilan method run(). Saat method run() dipanggil, status thread berubah menjadi runnable, artinya thread tersebut sudah memenuhi syarat untuk dijalankan oleh JVM. Thread yang sedang berjalan juga berada di status runnable.

 Blocked. Sebuah thread dikatakan berstatus blocked atau terhalang jika terjadi blocking statement, misalnya pemanggilan method sleep(). sleep() adalah suatu method yang menerima argumen bertipe integer dalam bentuk milisekon. Argumen tersebut menunjukkan seberapa lama thread akan “tidur”. Selain sleep(), dulunya dikenal method suspend(), tetapi sudah disarankan untuk tidak digunakan lagi karena mengakibatkan terjadinya deadlock. Thread akan menjadi runnable kembali jika interval method sleep()-nya sudah berakhir, atau pemanggilan method resume() jika untuk menghalangi thread tadi digunakan method suspend()

 Dead. Sebuah thread berada di status dead bila telah keluar dari method run(). Hal ini bisa terjadi karena thread tersebut memang telah menyelesaikan pekerjaannya di method run(), maupun karena adanya pembatalan thread. Status jelas dari sebuah thread tidak dapat diketahui, tetapi method isAlive() mengembalikan nilai boolean untuk mengetahui apakah thread tersebut dead atau tidak.

Pembentukan Thread dalam java

Untuk membuat thread dalam java terdapat dua cara :  Extends class Thread

Untuk menjalankan thread, dapat dilakukan dengan memanggil method start(). Saat start() dijalankan, maka sebenarnya method run() dari class akan dijalankan. Jadi untuk membuat thread, harus mendefinisikan method run() pada definisi class. Konstruktor dari cara ini adalah :

SubThread namaObject = new SubThread(); namaObject.start();

 Implements interface Runnable

Cara ini merupakan cara yang paling sederhana dalam membuat thread. Runnable merupakan unit abstrak, yaitu kelas yang mengimplementasikan interface ini hanya cukup

mengimplementasikan fungsi run(). Dalam mengimplementasi fungsi run(), kita akan

(6)

MyThread myObject= new MyThread(); Thread namaObject = new Thread(myObject);

Atau dengan cara singkat seperti : New Thread(new ObjekRunnable());

MyThread merupakan class yang mengimplementasikan interface dari Runnable, dan object dari class MyThread akan menjadi parameter instansi object class Thread.

Terdapat macam-macam method dalam komunikasi antar thread, yaitu:

 Method wait() menyebabkan thread terakhir yang mengakses obyek melepaskan kunci obyek dan menunggu sampai thread lain yang mengambil kunci obyek tersebut melepaskannya kembali ke obyek. Terdapat 2 jenis method wait(), yaitu :

a. Wait()menunggu sampai waktu tak berhingga sampai ada thread yang menyerahkan kunci obyek kepada obyek bersangkutan.

b. Wait ( long timeout ) menunggu sampai timeout milidetik.

 Method notify() akan menyebabkan thread pemegang kunci obyek melepaskan kunci obyek dan obyek pemilik kunci memilih salah satu thread pada state BLOCKED in object’s wait pool untuk diubah state-nya ke BLOCKED in object’s lock pool.

 Method notifyAll() akan menyebabkan thread pemegang kunci obyek melepaskan kunci obyek dan obyek pemilik kunci memindahkan semua thread yang berada pada state BLOCK in object’s wait pool ke state BLOCKED in object’s lock pool.

 Method suspend() berbeda dengan stop(). Method ini mengambil thread tertentu dan menyebabkannya berhenti tanpa menghancurkan thread di bawahnya atau keadaan thread yang berjalan sebelumnya. Jika suatu thread di-suspend, panggil method resume() padathread yang sama untuk menjalankannya lagi.

 Resume() method ini digunakan untuk menghidupkan method yang di-suspend. Tidak ada jaminan bahwa thread yang dijalankan kembali akan berjalan dengan baik karena mungkin sudah ada thread dengan prioritas lebih tinggi yang berjalan

 Stop() method ini menyebabkan thread segera berhenti. Ini sering dijadikan cara tercepat untuk mengakhiri suatu thread khususnya jika method ini dieksekusi pada thread yang berlaku. Pada kasus ini, baris program setelah pemanggilan method stop() tidak pernah dieksekusi karena konteks jalinan musnah sebelum stop() selesai.

(7)

Dalam Java kita dapat membuat prioritas suatu thread relative terhadapa thread yang lain. Sehingga thread yang mempunyai prioritas lebih tinggi mempunyai kesempatan lebih besar untuk mengakses suatu sources

Java Virtual Machine memilih thread yang runnable dengan prioritas tertinggi. Semua thread java mempunyai prioritas dari 1 sampai 10. Prioritas tertinggi 10 dan berakhir dengan 1 sebagai prioritas terendah. Sedangkan prioritas normal adalah 5.

 Thread.MIN_PRIORITY = thread dengan prioritas terendah.  Thread.MAX_PRIORITY = thread dengan prioritas tertinggi.  Thread.NORM_PRIORITY = thread dengan prioritas normal.

Saat thread baru dibuat ia mempunyai prioritas yang sama dengan thread yang menciptakannya. Prioritas thread dapat diubah dengan menggunakan setpriority() method. Bagaimanapun juga sebuah thread yang berjalan bersama-sama kadang-kadang membutuhkan resource atau method dari luar, butuh untuk berkomunikasi satu dengan yang lain sehingga dapat mengetahui status dan aktifitas mereka

Contoh: Permasalahan Produser-Konsumer 1 class TwoStrings {

2 static void print(String str1, String str2) { 3 System.out.print(str1);

4 try {

5 Thread.sleep(500);

6 } catch (InterruptedException ie) { 7 }

8 System.out.println(str2); 9 }

10 }

11 class PrintStringsThread implements Runnable { 12 Thread thread;

13 String str1, str2;

14 PrintStringsThread(String str1, String str2) { 15 this.str1 = str1;

16 this.str2 = str2;

17 thread = new Thread(this); 18 thread.start();

19 }

20 public void run() {

21 TwoStrings.print(str1, str2); 22 }

23 }

24 class TestThread {

25 public static void main(String args[]) {

26 new PrintStringsThread("Hello ", "there."); 27 new PrintStringsThread("How are ", "you?");

(8)

28 new PrintStringsThread("Thank you ",

29 "very much!"); 30 }

31 }

Contoh hasil :

Hello How are Thank you there. you? very much!

Mengunci sebuah object:

- Untuk memastikan bahwa hanya satu thread yang mendapatkan hak akses kedalam method tertentu

- Java memperbolehkan penguncian terhadap sebuah object termasuk method-method-nya dengan menggunakan monitor

o Object tersebut akan menjalankan sebuah monitor implicit pada saat object dari method sinkronisasi dipanggil

o Sekali object tersebut dimonitor, monitor tersebut akan memastikan bahwa tidak ada thread yang akan mengakses object yang sama

- Sinkronisasi sebuah method:

o Menggunakan keyword synchronized

o Dapat menjadi header dari pendefinisian method

o Dapat mensinkronisasi object dimana method tersebut menjadi anggota dari

synchronized (<object>) {

//statements yang akan disinkronisasikan }

Contoh Synchronized Pertama 1 class TwoStrings {

2 synchronized static void print(String str1, 3 String str2) { 4 System.out.print(str1);

5 try {

6 Thread.sleep(500);

7 } catch (InterruptedException ie) { 8 }

9 System.out.println(str2); 10 }

11 }

12 class PrintStringsThread implements Runnable { 13 Thread thread;

14 String str1, str2;

15 PrintStringsThread(String str1, String str2) { 16 this.str1 = str1;

17 this.str2 = str2;

18 thread = new Thread(this); 19 thread.start();

(9)

20 }

21 public void run() {

22 TwoStrings.print(str1, str2); 23 }

24 }

25 class TestThread {

26 public static void main(String args[]) {

27 new PrintStringsThread("Hello ", "there."); 28 new PrintStringsThread("How are ", "you?"); 29 new PrintStringsThread("Thank you ",

30 "very much!"); 31 } 32 } Contoh Hasil: Hello there. How are you?

Thank you very much! Contoh Synchronized Kedua : 1 class TwoStrings {

2 static void print(String str1, String str2) { 3 System.out.print(str1);

4 try {

5 Thread.sleep(500);

6 } catch (InterruptedException ie) { 7 }

8 System.out.println(str2); 9 }

10 }

11 class PrintStringsThread implements Runnable { 12 Thread thread; 13 String str1, str2; 14 TwoStrings ts; 15 PrintStringsThread(String str1, String str2, 16 TwoStrings ts) { 17 this.str1 = str1; 18 this.str2 = str2; 19 this.ts = ts;

20 thread = new Thread(this); 21 thread.start();

22 }

23 public void run() { 24 synchronized (ts) { 25 ts.print(str1, str2); 26 } 27 } 28 } 29 class TestThread {

(10)

30 public static void main(String args[]) { 31 TwoStrings ts = new TwoStrings();

32 new PrintStringsThread("Hello ", "there.", ts); 33 new PrintStringsThread("How are ", "you?", ts); 34 new PrintStringsThread("Thank you ",

35 "very much!", ts); 36 }}

KOMUNIKASI ANTAR THREAD: METHODS

Methods untuk komunikasi Interthread

public final void wait()

Menyebabkan thread ini menunggu sampai thread yang lain memanggil notify atau

notifyAll method dari object ini. Hal ini dapat menyebabkan InterruptedException. public final void notify()

Membangunkan thread yang telah memanggil method wait dari object yang sama. public final void notifyAll()

Membangunkan semua thread yang telah memanggil method wait dari object yang sama.

(11)

Contoh Produsen-Konsumen 1 class SharedData { 2 int data;

3 synchronized void set(int value) {

4 System.out.println("Generate " + value); 5 data = value;

6 }

7 synchronized int get() {

8 System.out.println("Get " + data); 9 return data;

10 } 11 }

12 class Producer implements Runnable { 13 SharedData sd;

14 Producer(SharedData sd) { 15 this.sd = sd;

16 new Thread(this, "Producer").start(); 17 }

18 public void run() {

19 for (int i = 0; i < 10; i++) {

20 sd.set((int)(Math.random()*100)); 21 }

22 } 23 }

24 class Consumer implements Runnable { 25 SharedData sd;

26 Consumer(SharedData sd) { 27 this.sd = sd;

28 new Thread(this, "Consumer").start(); 29 }

30 public void run() {

31 for (int i = 0; i < 10 ; i++) { 32 sd.get();

33 } 34 } 35 }

36 class TestProducerConsumer {

37 public static void main(String args[]) 38 throws Exception {

39 SharedData sd = new SharedData(); 40 new Producer(sd);

41 new Consumer(sd); 42 }}

Contoh hasil

Generate 8 Generate 49 Get 85

Generate 45 Get 49 Get 85

Generate 52 Generate 35 Get 85

(12)

Get 65 Generate 39 Get 35

Generate 23 Get 39 Get 35

Get 23 Generate 85

Contoh Produsen-Konsumen yang telah diperbaiki 1 class SharedData {

2 int data;

3 boolean valueSet = false;

4 synchronized void set(int value) {

5 if (valueSet) { //hanya dihasilkan jika mempumyai sebuah nilai

6 try { 7 wait();

8 } catch (InterruptedException ie) { 9 } 10 } 11 System.out.println("Generate " + value); 12 data = value; 13 valueSet = true; 14 notify(); 15 }

16 synchronized int get() { 17 if (!valueSet) {

18 //producer belum memiliki suatu nilai 19 try {

20 wait();

21 } catch (InterruptedException ie) { 22 } 23 } 24 System.out.println("Get " + data); 25 valueSet = false; 26 notify(); 27 return data; 28 } 29 } 30

31 /* Bagian kode tertentu tidak berubah. */

Contoh hasil :

Generate 76 Generate 48 Generate 65

Get 76 Get 48 Get 65

Generate 25 Generate 29 Generate 38

Get 25 Get 29 Get 38

Generate 34 Generate 26 Generate 46

Get 34 Get 26 Get 46

Generate 84 Get 84

Generate 86 Get 86

(13)

Ringkasan

Sinkronisasi

Mengunci sebuah Object Keyword synchronized

Method header Object

Komunikasi Antar Thread (Interthread) Methods

wait notify notifyAll

Referensi

Dokumen terkait