Anda di halaman 1dari 24

[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Thread
Multithreading adalah suatu fitur dalam bahasa pemrograman yang
memungkinkan kita membuat dua alur atau lebih dalam sebuah program untuk
melakukan beberapa hal secara “bersamaan” (sebenarnya tidak seratus persen
bersamaan pada mesin dengan satu prosesor, namun sistem memberikan giliran kepada
dua proses atau lebih untuk bekerja secara bergantian dengan waktu yang sangat cepat).
Program yang paling mudah memberikan contoh dalam hal ini adalah web browser
yang memungkinkan kita membaca dokumen sambil mendengarkan musik dan
melakukan hal lainnya. Java dan Object Pascal (Delphi) adalah contoh bahasa
pemrograman yang memungkinkan kita membuat
fitur multithreading dengan cukup mudah.

Tujuan kita membuat program dengan kemampuan multithreading adalah:


¾ Menghindari bottleneck (dengan hanya sebuah thread, program harus
menghentikan semua operasi ketika sedang menunggu sebuah proses yang lambat,
misalnya mengakses file dalam harddisk, berkomunikasi antarjaringan, atau
menampilkan fitur multimedia);
¾ Mengatur perilaku program menjadi lebih baik dan efisien (sebuah program dapat
diorganisasikan menjadi beberapa proses secara “paralel”, yang prioritasnya bisa
diatur sehingga pemanfaatan CPU menjadi lebih efisien);
¾ Multiprocessing. Jika sebuah mesin menggunakan lebih dari satu prosesor dan
didukung oleh sistem operasi yang dapat mendukung multi processing, maka
penggunaan thread dapat dilakukan oleh masing-masing prosesor sehingga proses
yang terjadi benar-benar terjadi secara bersamaan.

Membuat Thread

Ada beberapa cara untuk membuat Thread di Java, yaitu:


¾ Membuat sebuah kelas turunan dari Thread dan mengoverride method run;
¾ Mengimplementasikan interface Runnable dan mengimplementasikan method
run.

Pada Delphi, Thread dapat dibuat dengan membuat sebuah kelas turunan dari
TThread dan mengoverride method Execute.

Contoh pada Java:

1 package com.wisnuwidiarta.thread;
2
3 import java.util.Calendar;
4
5 public class BomWaktu extends Thread {
6
7 private boolean enabled = false;

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

8
9 public static
s void main(S
String[] args)
a {
10 BomW
Waktu bom
m = new Bo
omWaktu();
;
11 bom.setEnabled(true);
12 bom.start();
13
14 try {
System.out.printl
ln("Dalam waktu 10 detik, bom
b
15 aka
an meledak
k...");
16 Thread.sleep(1000
00);
17 } ca
atch (InterruptedE
Exception e) {
18 }
19
20 bom.setEnabled(false);
21 Syst
tem.out.println("B
Bum !!!");
;
22 }
23
24 public void
v run() {
25 whil
le (isEnabled()) {
26 try {
27 Calendar now = Calendaar.getInstance();
System.out.pr
rintln(noww.get(Calendar.HOUUR) +
28 ":"
" +
now
w.get(Calendar.MINNUTE) +
29 ":"
" +
30 now
w.get(Calendar.SECCOND));
31 Thread.sleep(
(1000);
32 } catch (Interrup
ptedExcepttion e) {
33 }
34 }
35 }
36
37 private boolean isEnabled
d() {
38 retu
urn enabled ;
39 }
40
41 public void
v setEnabled (b
boolean ac
ctive) {
42 this
s.enabled
d = active
e;
43 }
44 }

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
13\java\com\wisn nuwidiarta\thread.

Keluaran
n dari prog
gram di atass adalah:

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Dalam waktu 10 detik, bom akan meledak...


8:29:46
8:29:47
8:29:48
8:29:49
8:29:50
8:29:51
8:29:52
8:29:53
8:29:54
8:29:55
Bum !!!

Cara kerja program di atas lebih kurang adalah sebagai berikut:

• Pertama-tama program akan menginisialisasi variabel private enabled


dengan nilai false (baris ke ke-7)
• Variabel dengan nama bom yang tipenya BomWaktu dibuat dan diinisialisasi
(baris ke-10)
• Method setEnabled dengan parameter true dipanggil sehingga variabel enabled
kini bernilai true
• Method start merupakan warisan dari kelas Thread. Karena kelas BomWaktu
turunan dari kelas Thread, maka method start yang sifatnya public, dapat diakses
oleh instance dari kelas BomWaktu
• Ketika method start sebuah thread dipanggil, jika thread tersebut belum pernah
dijalankan, maka thread tersebut akan dijalankan (method run akan dipanggil).
Namun jika thread tersebut telah dijalankan dan dipaksa untuk start, maka
exception IllegalThreadStateException akan dipicu
• Program mencetak Dalam waktu 10 detik, bom akan meledak... Lalu tidur selama
10 detik
• Selanjutnya kontrol program beralih ke dalam method run, dan setiap detiknya
memunculkan waktu pada layar
• Setelah tidur selama 10 detik, program beralih ke baris 20, menghentikan timer
dalam method run, dan mencetak ke layar Bum !!!

Program tersebut dapat dijalankan melalui editor NetBeans atau melalui command line
dengan perintah:
java.exe com.wisnuwidiarta.thread.BomWaktu
Pastikan java.exe sudah berada dalam path, atau gunakan path lengkap dengan
direktorinya, misalnya D:\java\jdk1.5\bin\java.exe. Pemanggilan pada
command line di atas harus diletakkan pada folder di atas folder com. Jika Anda ingin
memanggil dari sembarang folder, jangan lupa gunakan parameter –cp (cp berarti
classpath) dan sertakan path lengkap hingga ke folder di atas folder com.

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Perhatikan pada gambar di atas, bahwa program java.exe berada pada


d:\Wisnu\Misc\Installer\Java\jdk1.5.0\bin,
dan folder com/wisnuwidiarta/thread/BomWaktu.class berada pada folder
d:\Wisnu\Project\Writing Book\Dari Pascal ke Java\Code\Bab 12\Java, dan
pemanggilan kelas BomWaktu dilakukan dari folder c:\.

Jika kita bandingkan dengan Delphi, maka programnya lebih kurang sebagai berikut:

1 program BomWaktu;
2
3 {$APPTYPE CONSOLE}
4
5 {%TogetherDiagram 'ModelSupport_BomWaktu\default.txaPackage'}
6
7 uses
8 SysUtils, Classes;
9
10 type
11 TBomWaktu = class(TThread)
12 private FEnabled: boolean;
13 protected procedure Execute; override;
14 public property Enabled: boolean read FEnabled write FEnabled;
15 end;
16 { TBomWaktu }
17
18 procedure TBomWaktu.Execute;
19 begin
20 while FEnabled do
21 begin
22 writeln(FormatDateTime('HH:MM:SS', Now));
23 Sleep(1000);

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

24 end;
25 end
d;
26
27 var
r
28 bom: TBomWWaktu;
29 beg
gin
30 bom := TBomWaktu.
T Create(tru
ue);
31 bom.Enabbled := true;
32 bom.Resuume;
33
34 writeln('Dalam waktu 10 det
tik, bom akan meleda
ak...');
35 Sleep(10
0000);
36 bom.Enab
bled := False;
37 writeln('Bum !!!');
38 readln;
39 end
d.

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
12\pasccal\Bom Wa aktu.

Kelas untuk
K k mewakili thread di Java adalaah Thread
d, sedangka an pada Deelphi
adalah TThread.
T Method un ntuk dioverride pada
a Java adallah run, seedangkan pada
p
Delphi adalah Execute. Ba agian progrram yang akan dibuuat sebagaii thread, harus
h
diletakk
kan dalam method
m terssebut.

Ada dua
a cara untukk membuatt thread di Java,
J yaitu:
• Membuat
M keelas turunan
n dari Thre
ead
• Membuat
M keelas yang mengimplem
m mentasikan interface Runnable
R

Cara yang lebih


C l baik dalam ban nyak kasus adalah carra yang ked dua. Menggapa?
Meskipu un cara yan ng pertama a lebih muudah untuk k diimplemmentasikan, namun da alam
sudut pa andang pem mrograman n berorienttasi objek (OOP),
( caraa kedua lebbih tepat untuk
u
digunak kan. Pada umumnya
u k
kita membu utuhkan seebuah threa ad agar seb buah pekerrjaan
‘asal’ bissa dilakukaan dengan thread,
t bukkan untuk membuat
m seebuah kelass yang memmiliki
spesifika asi yang leb bih khususs daripada sebuah Th hread. Misa alnya, kita membuat kelas
k
PersegiP Panjang dengan
d jalan mewarrisi kelas BangunD Datar, kareena kita tahu
PersegiP Panjang ad dalah Bang gunDatar dengan sp pesifikasi yang
y lebih
h khusus. Jika
keperlua an kita hanya meelakukan sesuatu dengan d th
hread, leb bih baik kita
mengim mplementasiikan interfa ace Runnab ble, sehing k lebih beebas digunakan
gga kelas kita
untuk mewarisi
m dari kelas lain
n. Ingat, Ja
ava hanya memungkin
m nkan kita menurunkan n dari
satu kelas, namun n dapat mengimplem
m mentasikan n banyak interface.
i J
Jika kita akan
menggu unakan inteerface Run nnable, kiita tetap butuh
b instaance dari Thread untuk
u
menjala ankan kelas kita.
M
Mari kita perhatikan contoh
c memmbuat Thrread denga an menggun nakan interrface
Runnab ble berikut ini.

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

1 package com.wisnuwidiarta.thread;
2
3 import java.util.Calendar;
4
5 public class BomWaktuDenganRunnable implements Runnable {
6
7 private boolean enabled = false;
8
9 public static void main(String[] args) {
10 BomWaktu bomWaktu = new BomWaktu();
11 bomWaktu.setEnabled(true);
12 Thread bom = new Thread(bomWaktu);
13 bom.start();
14
15 try {
System.out.println("Dalam waktu 10 detik, bom
16 akan meledak...");
17 Thread.sleep(10000);
18 } catch (InterruptedException e) {
19 }
20
21 bomWaktu.setEnabled(false);
22 System.out.println("Bum !!!");
23 }
24
25 public void run() {
26 while (isEnabled()) {
27 try {
28 Calendar now = Calendar.getInstance();
System.out.println(now.get(Calendar.HOUR) +
29 ":" +
now.get(Calendar.MINUTE) +
30 ":" +
31 now.get(Calendar.SECOND));
32 Thread.sleep(1000);
33 } catch (InterruptedException e) {
34 }
35 }
36 }
37
38 private boolean isEnabled() {
39 return enabled ;
40 }
41
42 public void setEnabled (boolean active) {
43 this.enabled = active;

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

44 }
45
46 }

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
13\java\com\wisn nuwidiarta\thread.

Perhatikkan pada co ontoh di attas, keluara


annya sama a dengan keeluaran BomWaktu.java.
Hal yan ng berbeda hanya terlletak pada baris ke-10 0 dan baris ke-12, ba
ahwa kita perlu
p
instancee dari kelas Thread un ntuk menjaalankan thrread tersebuut dengan method
m start.
Ingat ba ahwa denga an mengimmplementassikan interfface Runna able, sebuuah kelas hanya
“menand datangani kontrak”
k bahwa ia ak kan mengim mplementassikan meth hod run. Hanya
itu saja. Titik. Untu
uk membua atnya menjadi sebuah thread, bu uat sebuah variabel
v denngan
jenis Thhread (atau u turunannnya), dan pada
p constrructornya, berikan
b parrameter seb
buah
instancee dari Runnnable.
Ada carra lain untu uk mendap patkan efek k thread, dengan
d mennggunakan bantuan inner
i
class. Keelas utamaanya sendirri tidak perrlu mewarissi dari kelaas Thread dan tidak pula
perlu mengimplem
m mentasikan interface Runnable. Namun jelas, innerr classnya yang
melakuk kannya. Con ntohnya addalah sebaga ai berikut:

1 pac
ckage com.wisnuwidiarta.thr read;
2
3 pub
blic class
s InnerClassThread d {
4
5 public InnerClas
I sThread() {
6 Thre
ead t = n ew Threadd(new Runn
nable() {
7
8 public void
v run() {
9 int i=1;
10 while (i <= 3) 3 {
11 System.ouut.println
n(i++);
12 }
13 }
14
15 });
16 t.st
tart();
17 }
18
19 public static
s void main(S String[] args)
a {
20 new InnerClassThread( ();
21 }
22
23 }

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Jangan bingung dengan contoh di atas. Kelas utama pada contoh di atas adalah
InnerClassThread. Di dalam constructor kelas tersebut, ada dua baris statement,
yang pertama dimulai dari baris ke-6 hingga baris ke-15, sedangkan statement kedua
terletak pada baris ke-16. Baris ke-6 menunjukkan bahwa kita memesan sebuah variabel
atau instance dari kelas Thread dengan nama t. Variabel tersebut kita inisialisasi
dengan constructor kelas Thread yang membutuhkan sebuah parameter berjenis
Runnable. Namun seperti yang kita lihat, kelas utama kita, InnerClassThread, tidak
mengimplementasi Runnable. Sehingga kita tidak dapat membuat instance dari kelas
InnerClassThread untuk kita passing ke dalam constructor Thread tersebut.
Untungnya, Java memiliki fitur kelas anonymous, kelas tanpa nama, yang dapat kita
buat seketika tanpa harus kita beri nama. Alih-alih membuat sebuah kelas pembantu
kecil yang mengimplementasikan interface Runnable untuk kita jadikan “umpan” ke
dalam constructor Thread pada baris ke-6, kita dapat langsung membuat instance
tanpa nama dengan perintah :

new Runnable() {

public void run() {


int i=1;
while (i <= 3) {
System.out.println(i++);
}
}

Mengapa ada kurung kurawal setelah Runnable()? Kita tahu bahwa Runnable adalah
sebuah interface. Ia tidak memiliki implementasi dari method run( ). Oleh karenanya,
kita membuat instance dari kelas Runnable sekaligus mengimplementasikan method
run, agar objek yang kita ciptakan menjadi lengkap. Tanpa mengimplementasikan
method run, maka Runnable hanyalah sesuatu yang abstrak, tidak kongkrit. Sesuatu
yang tidak kongkrit, tidak dapat dibuat instancenya.

Ok. Sekarang kita lihat daur hidup sebuah Thread.

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

New

Sleep
Runnable

Blocked

Running
Waiting

Dead

Kita mulai dari New. Kondisi ini tercapai ketika thread baru saja dibuat, dan
diinstantiasikan. Contohnya adalah:

Thread bom = new Thread(bomWaktu);

Kita bandingkan dengan proses pembuatan film. Misalkan aktor adalah thread. Aktor
memasuki tahapan “new” ketika ia dicasting (dipilih untuk memerankan sebuah peran).
Ia belum boleh berakting, hingga sutradara menentukannya. Sutradara dalam dunia
thread bisa jadi adalah operating system atau scheduler, yang menentukan kapan
sebuah thread dapat giliran untuk beraksi (acting).
Setelah sebuah thread dijalankan (dengan memanggil method start), maka ia
beralih ke kondisi Runnable. Artinya siap-siap diminta untuk beraksi. Dalam dunia
perfilman, berarti sutradara menyuruh sang aktor untuk bersiap-siap di lokasi shooting.
bom.start();
Ingat bahwa perintah di atas bukan untuk memulai akting! Tapi untuk bersiap-
siap akting, kalau gilirannya sudah siap. Bisa jadi seorang aktor mulai berakting ketika
kereta baru saja lewat, atau menunggu giliran aktor lain selesai berakting. Ketika
sutradara menentukan untuk berakting, barulah seorang aktor akan mulai berakting.
Dalam dunia thread, ketika O/S atau thread scheduler menyuruhnya berjalan, barulah
thread itu berjalan. Sebuah thread berjalan ketika ia memasuki method run. Semua
script yang harus dilakukan oleh sang thread, eh maksud saya sang aktor, didefinisikan
pada method tersebut.
Ketika sedang berjalan, sebuah thread bisa keluar dari kondisi running menjadi
sleep, blocked, atau waiting akibat dari beberapa hal, yaitu:
blocked karena thread menunggu proses I/O untuk selesai;
blocked karena thread mencoba memanggil method yang disynchronized, dan lock
objecknya belum tersedia;

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

sleep ketika dalam method run ada perintah untuk sleep (untuk membangunkannya
gunakan method interrupt, atau biarkan waktu tidurnya berakhir), contohnya
adalah :
try {
Calendar now = Calendar.getInstance();

System.out.println(now.get(Calendar.HOUR) + ":" +

now.get(Calendar.MINUTE) + ":" +

now.get(Calendar.SECOND));
Thread.sleep(1000);
} catch (InterruptedException e) {
}
waiting karena ada pemanggilan method wait (untuk berhenti menunggu, gunakan
notify atau notifyAll).
Kalau dibandingkan dengan dunia perfilman, bisa dibandingkan ketika sutradara
mengatakan “cut” atau ketika akting beralih pada aktor lain. Si aktor harus “menunggu”
gilirannya, hingga ia harus berakting kembali. Setelah syuting selesai, maka selesailah
tugas aktor tersebut. Dalam dunia thread, sebuah thread menjadi mati (dead atau not
alive) ketika semua perintah dalam method run selesai dilakukan dan kontrol telah
keluar dari method tersebut.

Sinkronisasi Thread

Sebuah thread yang mengakses sebuah objek yang sama, dan keduanya
mengubah kondisi atau status dari objek tersebut, maka ada kemungkinan objek
tersebut mengalami inkonsistensi data atau menghasilkan program yang tidak
diinginkan. Agar program berfungsi dengan normal, ada kalanya kita membutuhkan
sinkronisasi thread. Sinkronisasi thread dilakukan dengan menggunakan kata kunci
synchronized.
Mari kita bayangkan sebuah perpustakaan yang hanya memiliki sebuah buku,
dan ada dua peminjam yang akan meminjam buku tersebut. Tanpa disinkronisasi,
peminjaman buku tersebut akan menjadi tidak valid, karena ada dua objek berbeda
yang mencoba mengakses satu-satunya resource, yaitu buku. Dalam kejadian
sesungguhnya, bisa saja ada dua aplikasi yang berebut mengakses printer, misalnya.

1 package com.wisnuwidiarta.thread;
2
3 public class Perpustakaan {
4
static Buku satuSatunyaBuku = new Buku("Dari Pascal ke
5 Java");
6
7 public static void main(String[] args) {
8 Peminjam deNiro = new Peminjam("De Niro");
9 Peminjam alPacino = new Peminjam("Al Pacino");

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

10
11 deNiro.pinjam(satuSatunyaBuku);
12 alPacino.pinjam(satuSatunyaBuku);
13
14 Thread deNiroThread = new Thread(deNiro);
15 Thread alPacinoThread = new Thread(alPacino);
16 deNiroThread.setName(deNiro.getNamaPeminjam());
17 alPacinoThread.setName(alPacino.getNamaPeminjam());
18
19 deNiroThread.start();
20 alPacinoThread.start();
21 }
22
23 }
24
25 class Buku {
26 private String judulBuku;
27 private boolean sedangDipinjam = false;
28 private Peminjam peminjamBuku;
29
30 public Buku(String judul) {
31 judulBuku = judul;
32 }
33
34 public void dipinjam(Peminjam peminjam) {
35 sedangDipinjam = true;
36 peminjamBuku = peminjam;
37 System.out.println("Buku " + judulBuku +
38 " sekarang sedang dipinjam oleh " +
39 peminjam.getNamaPeminjam() +".");
40 }
41
42 public void dikembalikan() {
43 sedangDipinjam = false;
44 System.out.println("Buku " + judulBuku +
45 " telah dikembalikan.");
46 peminjamBuku = null;
47 }
48
49 public boolean isDipinjam() {
50 return sedangDipinjam;
51 }
52
53 public String getJudulBuku() {
54 return judulBuku;
55 }
56

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

57 public Peminjam getPeminjamBuku() {


58 return peminjamBuku;
59 }
60 }
61
62 class Peminjam implements Runnable {
63 private Buku buku;
64 private String namaPeminjam;
65
66 public Peminjam (String nama) {
67 namaPeminjam = nama;
68 }
69
70 public void pinjam (Buku bukuDipinjam) {
71 buku = bukuDipinjam;
72 }
73
74 public void run() {
75 System.out.println("Thread " +
Thread.currentThread().getName() + " sedang
76 beraksi...");
77
78 if (buku.isDipinjam() == false) {
System.out.println(" Karena buku " +
79 buku.getJudulBuku() +
80 " tidak sedang dipinjam, maka " + namaPeminjam +
81 " berniat untuk meminjamnya.");
82
83 try {
84 System.out.println(" " + namaPeminjam +
85 " menuju ke rak buku...");
86 Thread.sleep(10);
87 } catch (InterruptedException e) { }
88 buku.dipinjam(this);
89 }
90 else {
91 System.out.println(" " + namaPeminjam +
92 " tidak bisa meminjam buku " +
buku.getJudulBuku() + " karena sedang dipinjam
93 oleh " +
94 buku.getPeminjamBuku().getNamaPeminjam() +".");
95 }
96 }
97
98 public Buku getBuku() {
99 return buku;
100 }
101

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

102 public String getNamaPem


minjam() {
103 ret
turn namaPeminjam;
104 }
105
106 }

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
13\java\com\wisn nuwidiarta\thread.

Jika dija
alankan, sallah satu kem
mungkinan
n dari jalann
nya program
m adalah seebagai
berikut:

Thread De Niro sedang be


eraksi...
Kare
ena buku Dari Pasc
cal ke Javva tidak sedang di
ipinjam, maka
m De Niro
berniat
t untuk meminjamny
ya.
De Niro
N menuju ke rak
k buku...
Thread Al Pacino sedang beraksi....
Kare
ena buku Dari Pasc
cal ke Javva tidak sedang di
ipinjam, maka
m Al
Pacino berniat untuk mem
minjamnya..
Al Pacino
P menuju ke rak
r buku....
Buku Da
ari Pascal ke Java
a sekarangg sedang dipinjam oleh De Niro.
N
Buku Da
ari Pascal ke Java
a sekarangg sedang dipinjam oleh Al Pacino.
P

Mengapa salah
M s satu kemungk kinan? Karrena tingk
kah laku thread sa
angat
ditentuk
kan dari sch
hedulernya
a. Dan beda
a JVM, run
ntime, dan O/S
O dapat mempengaaruhi
jalannya
a sebuah thread.

K lihat pa
Kita ada program
m di atas, sa
atu-satunyaa buku dipiinjam oleh dua orang yang
berbeda a, persis ketika
k De Niro men nuju ke rak buku, Al Pacino o juga berniat
meminja amnya. Akkhirnya karrena kedua anya mera asa yakin buku
b itu tidak
t ada yang
meminja am, maka masing-ma
m sing menda apat buku tersebut.
t Seekarang kitta lihat hasiilnya
setelah kita
k mensin nkronisasik
kan objek buuku. Artinyya ketika bu
uku sedang dipinjam, yang
lain tida
ak bisa mem
minjamnya. Perhatikan n method run
r yang dip perbaiki beerikut ini:

pu
ublic void run() {
System.out.print
tln("Threa
ad " +
Thread.currentTh
hread().ge
etName() + " sedan
ng beraksi
i...");

synchron
nized (bu
uku) {
if (buku.isD
Dipinjam()
) == falsee) {
System.o
out.printl
ln(" Karena bukuu " +
buku.ge
etJudulBuku() +
" tidak sedang di
ipinjam, maka
m " + namaPemin
njam +
" bernia
at untuk meminjamn
m ya.");

try {

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

System.out.println(" " + namaPeminjam +


" menuju ke rak buku...");
Thread.sleep(10);
} catch (InterruptedException e) { }
buku.dipinjam(this);
}
else {
System.out.println(" " + namaPeminjam +
" tidak bisa meminjam buku " +
buku.getJudulBuku() + " karena sedang dipinjam
oleh " +
buku.getPeminjamBuku().getNamaPeminjam()
+".");
}
}
}

Keluaran dari program dengan sinkronisasi di atas adalah:

Thread De Niro sedang beraksi...


Karena buku Dari Pascal ke Java tidak sedang dipinjam, maka De Niro
berniat untuk meminjamnya.
De Niro menuju ke rak buku...
Thread Al Pacino sedang beraksi...
Buku Dari Pascal ke Java sekarang sedang dipinjam oleh De Niro.
Al Pacino tidak bisa meminjam buku Dari Pascal ke Java karena
sedang dipinjam oleh De Niro.

Sekarang kita bandingkan dengan program yang mirip program di atas dengan Delphi:

1 program Perpustakaan;
2
3 {$APPTYPE CONSOLE}
4
5 {%TogetherDiagram 'ModelSupport_Perpustakaan\default.txaPackage'}
6
7 uses
8 SysUtils, Classes;
9
10 type
11 TBuku = class;
//forward declaration, agar TBuku dapat digunakan pada kelas
12 TPeminjam
13
14 TPeminjam = class(TThread)
15 private
16 FBuku: TBuku;
17 FNamaPeminjam: String;
18 public

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

19 constructor Create(nama: String;


20 CreateSuspended: Boolean); reintroduce;
21 procedure Pinjam(bukuDipinjam: TBuku);
22 procedure Execute; override;
23 function GetBuku: TBuku;
24 function GetNamaPeminjam: String;
25 end;
//style di atas adalah bentuk yang paling umum digunakan di
26 Delphi
27
28 TBuku = class
29 private FJudulBuku: String;
30 private FSedangDipinjam: boolean;
31 private FPeminjamBuku: TPeminjam;
32 public constructor Create(judul: String);
33 public procedure Dipinjam(peminjam: TPeminjam);
34 public procedure Dikembalikan;
35 public function IsDipinjam: boolean;
36 public function GetJudulBuku: String;
37 public function GetPeminjamBuku: TPeminjam;
38 end;
{style di atas tidak umum digunakan di Delphi, namun mungkin
39 terasa
40 familiar bagi programmer
41 java yang sedang membuat aplikasi di Delphi}
42
43 { TBuku }
44
45 constructor TBuku.Create(judul: String);
46 begin
47 FJudulBuku := judul;
48 end;
49
50 procedure TBuku.dikembalikan;
51 begin
52 FSedangDipinjam := False;
53 writeln('Buku ' + FJudulBuku +
54 ' telah dikembalikan.');
55 FPeminjamBuku := Nil;
56 end;
57
58 procedure TBuku.dipinjam(peminjam: TPeminjam);
59 begin
60 FSedangDipinjam := True;
61 FPeminjamBuku := peminjam;
62 writeln('Buku ' + FJudulBuku +
63 ' sekarang sedang dipinjam oleh ' +
64 FPeminjamBuku.GetNamaPeminjam + '.');

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

65 end;
66
67 function TBuku.getJudulBuku: String;
68 begin
69 Result := FJudulBuku;
70 end;
71
72 function TBuku.getPeminjamBuku: TPeminjam;
73 begin
74 Result := FPeminjamBuku;
75 end;
76
77 function TBuku.isDipinjam: boolean;
78 begin
79 Result := FSedangDipinjam;
80 end;
81
82 { TPeminjam }
83
constructor TPeminjam.Create(nama: String; CreateSuspended:
84 Boolean);
85 begin
86 inherited Create(CreateSuspended);
87 FNamaPeminjam := nama;
88 end;
89
90 procedure TPeminjam.Execute;
91 begin
92 if (FBuku.isDipinjam() = False) then
93 begin
94 writeln(' Karena buku ' + FBuku.getJudulBuku +
95 ' tidak sedang dipinjam, maka ' + FNamaPeminjam +
96 ' berniat untuk meminjamnya.');
97
98 writeln(' ' + FNamaPeminjam +
99 ' menuju ke rak buku...');
100 sleep(10);
101 FBuku.dipinjam(Self);
102 end
103 else
104 begin
105 writeln(' ' + FNamaPeminjam +
106 ' tidak bisa meminjam buku ' +
107 FBuku.getJudulBuku + ' karena sedang dipinjam oleh ' +
108 FBuku.getPeminjamBuku.getNamaPeminjam + '.');
109 end;
110 end;

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

111
112 fu
unction TPeeminjam.GetBuku: TBu
uku;
113 begin
114 Result := FBuku;
115 en
nd;
116
117 fu
unction TPeeminjam.GetNamaPemin
njam: Strin
ng;
118 begin
119 Result := FNamaPeminjam;
120 en
nd;
121
122 pr
rocedure TPPeminjam.Pinjam(buku
uDipinjam: TBuku);
123 begin
124 FBuku :=
: bukuDipinjam;
125 en
nd;
126
127 va
ar
128 satuSatunnyaBuku: TBuku;
129 deNiro, alPacino:
a TPeminjam;
;
130 begin
131 deNiro := TPeminjam.Create
e('De Niro', True);
132 deNiro..FreeOnTerminate := True;
133 alPacinno := TPeminjam.Crea
ate('Al Pacino', Truue);
134 alPacinno.FreeOnTerminate :=
: True;
135
136 satuSat
tunyaBuku := TBuku.C
Create('Dari Pascal Ke Java');
137 deNiro.
.Pinjam(satuSatunyaB
Buku);
138 alPacin
no.Pinjam(satuSatuny
yaBuku);
139
140 deNiro.
.Resume;
141 alPacin
no.Resume;
142
143 readln;
;
144 en
nd.

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab 13\
pascal\P
Perpustaka aan\Tanpa Synchronizzed.

a adalah seb
Hasilnya bagai berik
kut:

Kare
ena buku Dari Pasc
cal Ke Javva tidak sedang di
ipinjam, m
maka De Niro
berniat
t untuk meminjamny
ya.
De Niro
N menuju ke rak
k buku...
Kare
ena buku Dari Pasc
cal Ke Javva tidak sedang di
ipinjam, maka
m Al
Pacino berniat untuk mem
minjamnya..
` Al Pacino menuju ke rak buku....

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Buku Dari Pascal Ke Java sekarang sedang dipinjam oleh De Niro.


Buku Dari Pascal Ke Java sekarang sedang dipinjam oleh Al Pacino.

Sayangnya, method synchronize milik TThread menggunakan message loop,


sehingga tidak dapat digunakan pada aplikasi console. Namun demikian, untuk
melakukan sinkronisasi, Delphi memiliki beberapa cara, salah satunya adalah dengan
menggunakan critical section (selain dengan Mutex dan Semaphore). Modifikasi
program di atas seperti pada penggalan program berikut:

var
criticalSection: TCriticalSection;

procedure TPeminjam.pinjamBuku;
begin
criticalSection.Acquire;
if (FBuku.isDipinjam = False) then
begin
writeln(' Karena buku ' + FBuku.getJudulBuku +
' tidak sedang dipinjam, maka ' + FNamaPeminjam +
' berniat untuk meminjamnya.');
writeln(' ' + FNamaPeminjam + ' menuju ke rak buku...');
sleep(10);
FBuku.dipinjam(Self);
end
else
begin
writeln(' ' + FNamaPeminjam +' tidak bisa meminjam buku ' +
FBuku.getJudulBuku + ' karena sedang dipinjam oleh ' +
FBuku.getPeminjamBuku.getNamaPeminjam + '.');
end;
criticalSection.Release;
end;

var
satuSatunyaBuku: TBuku;
deNiro, alPacino: TPeminjam;
begin
deNiro := TPeminjam.Create('De Niro', True);
deNiro.FreeOnTerminate := True;
alPacino := TPeminjam.Create('Al Pacino', True);
alPacino.FreeOnTerminate := True;

satuSatunyaBuku := TBuku.Create('Dari Pascal Ke Java');


deNiro.Pinjam(satuSatunyaBuku);
alPacino.Pinjam(satuSatunyaBuku);

criticalSection := TCriticalSection.Create;
deNiro.Resume;
alPacino.Resume;

readln;
criticalSection.Free;
end.

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

Hasilnya adalah sebagai berikut:

Karena buku Dari Pascal Ke Java tidak sedang dipinjam, maka De Niro
berniat untuk meminjamnya.
De Niro menuju ke rak buku...
Buku Dari Pascal Ke Java sekarang sedang dipinjam oleh De Niro.
Al Pacino tidak bisa meminjam buku Dari Pascal Ke Java karena
sedang dipinjam oleh De Niro.

Mari kita lihat contoh lain, berupa penggunaan method sleep dan interrupt untuk
thread di Java.

1 package com.wisnuwidiarta.thread;
2
3 public class SleepingBeauty implements Runnable {
4
5 private String name;
6
7 public SleepingBeauty(String name) {
8 this.name = name;
9 }
10
11 public static void main(String[] args) {
SleepingBeauty aLovelyPrincess = new
12 SleepingBeauty("Hot Princess");
13 Thread sleeper = new Thread(aLovelyPrincess);
PrinceCharming aCoolAndHandsomePrince = new
14 PrinceCharming(sleeper);
15 Thread waker = new Thread(aCoolAndHandsomePrince);
16 sleeper.start();
17 waker.start();
18 }
19
20 public void run() {
21 boolean sleepForever = true;
22 while (sleepForever) {
23 try {
System.out.println(name + " is still
24 sleeping...");
25 Thread.sleep(1000);
26 } catch (InterruptedException e) {
27 sleepForever = false;
28 System.out.println("The princess is awake...");
29 }
30 }
31 }
32
33 }

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

34
35 cla
ass Prince
eCharming implemennts Runnab
ble {
36
37 private Thread princessThhread;
38
39 public PrinceCha
P rming(Thr
read sleep
per) {
40 prin
ncessThre ad = slee
eper;
41 }
42
43 public void
v run() {
44 try {
45 System.out.printlln("The pr
rince is running..
..");
46 Thread.sleep(50000);
System.out.printl
ln("The pr
rince is trying to
o wake
47 the
e princess
s...");
48 princessThread.innterrupt()
);
49 } ca
atch (InterruptedEException e) {
50 System.o ut.printl
ln("Failed
d...");
51 }
52 }
53
54 }

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
13\java\com\wisn nuwidiarta\thread.

Keluaran
n dari prog
gram di atass adalah:

Hot Pri
incess is still sl
leeping...
.
The pri
ince is running...
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
The pri
ince is trying to wake the princess...
Hot Pri
incess is still sl
leeping...
.
The pri
incess is awake...

Terkada
ang, keluara
annya adala
ah:

Hot Pri
incess is still sl
leeping...
.
The pri
ince is running ...
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
Hot Pri
incess is still sl
leeping...
.
The pri
ince is trying to wake the princess...

Wisnu Widiarta
W
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

The princess is awake...

Prioritas Thread

Thread dapat diberi prioritas tertentu, sesuai dengan keperluan. Tanpa penggunaan
prioritas, giliran untuk berjalan sebuah thread tergantung sepenuhnya pada scheduling
yang ada pada JVM dan mesin yang kita miliki. Mari kita lihat contoh berikut:

1 package com.wisnuwidiarta.thread;
2
3 public class ThreadTanpaPrioritas {
4
5 public static void main(String[] args) {
6 new Thread1().start();
7 new Thread2().start();
8 }
9
10 }
11
12 class Thread1 extends Thread {
13
14 public void run() {
15 while (true) {
16 System.out.println("1");
17 }
18 }
19
20 }
21
22 class Thread2 extends Thread {
23
24 public void run() {
25 while (true) {
26 System.out.println("2");
27 }
28 }
29
30 }

Keluaran program di atas, salah satunya adalah menampilkan angka 1 sebanyak 160
kali, lalu angka 2 dan angka 1 berselang-seling sebentar, lalu 2 sebanyak 120 kali dan
seterusnya. Jika masing-masing thread kita berikan prioritas yang berbeda, maka
hasilnya jadi berbeda.

1 package com.wisnuwidiarta.thread;
2

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

3 public class ThreadDenganPrioritas {


4
5 public static void main(String[] args) {
6 new Thread1().start();
7 new Thread2().start();
8 }
9
10 }
11
12 class Thread1 extends Thread {
13
14 public void run() {
15 setPriority(Thread.NORM_PRIORITY);
16 while (true) {
17 System.out.println("1");
18 }
19 }
20
21 }
22
23 class Thread2 extends Thread {
24
25 public void run() {
26 setPriority(Thread.NORM_PRIORITY + 1);
27 while (true) {
28 System.out.println("2");
29 }
30 }
31
32 }

Pada program di atas, angka 2 akan muncul jauh lebih sering daripada angka 1, karena
prioritas Thread1 lebih tinggi daripada prioritas Thread2. Jangan terlalu bergantung
pada prioritas thread untuk menentukan kebenaran program, karena tingkah laku
pengaturan prioritas ini tidak dijamin. Penggunaan prioritas lebih diutamakan untuk
mengatur efisiensi program, bukan kebenarannya.

Wait dan Notify

Mari kita lihat penggunaan wait dan notify yang akan diterapkan pada contoh
sleeping beauty di atas berikut ini.

1 package com.wisnuwidiarta.thread;
2
public class SleepingBeautyWithWaitAndNotify implements
3 Runnable {

Wisnu Widiarta
[CONTOH BAB BUKU DARI PASCAL KE JAVA]

4
5 private String name;
6
7 public SleepingBeautyWithWaitAndNotify(String name) {
8 this.name = name;
9 }
10
11 public static void main(String[] args) {
12 SleepingBeautyWithWaitAndNotify aLovelyPrincess =
13 new SleepingBeautyWithWaitAndNotify("Hot Princess");
14 Thread waiter = new Thread(aLovelyPrincess);
PrinceCharming aCoolAndHandsomePrince = new
15 PrinceCharming(waiter);
16 Thread waker = new Thread(aCoolAndHandsomePrince);
17
18 waiter.start();
19 waker.start();
20 }
21
22 public synchronized void run() {
23 System.out.println(name + " is still sleeping...");
24 try {
25 wait();
26 } catch (InterruptedException e) {
27 System.out.println("The princess is awake...");
28 }
29 }
30
31 public synchronized void kissSoftly() {
32 notify();
33 }
34
35 }
36
37 class PrinceCharmingWithNotify implements Runnable {
38
39 private SleepingBeautyWithWaitAndNotify princessThread;
40
public
PrinceCharmingWithNotify(SleepingBeautyWithWaitAndNotify
41 waiter) {
42 princessThread = waiter;
43 }
44
45 public void run() {
46 System.out.println("The prince is running ...");
47 try {

Wisnu Widiarta
[C
CONTOH BAB
B BUKU
U DARI PA
ASCAL KE
E JAVA]

48 Thread.sleep(5000
0);
49 princessThread.ki
issSoftly();
50 } ca Exception e) {
atch (InterruptedE
51 System.out.printl
ln("Failed
d...");
52 }
53 }
54
55 }

Kode dii atas dapatt ditemukan


n pada CD dalam
d foldeer Code\Ba
ab
13\java\com\wisn nuwidiarta\thread.

Keluaran
n pada prog
gram di ata
as adalah:
Hot Pri
incess is still sl
leeping...
.
The pri
ince is running ...
The pri
ince is trying to wake the princess...
The pri
incess is awake...

Perhatikkan bahwa untuk


u dapa
at menggun nakan wait t, kita haruss mendapattkan lock ob
bject
tersebutt terlebih da ahulu. Untu
uk itulah kiita menggu
unakan syn nchronize ed pada meethod
run pad da contoh tersebut. Tanpa meelakukannyya, sebuah exception akan mun ncul,
seperti berikut
b ini:
Excepti
ion in thread "Thr
read-0" ja
ava.lang.IllegalMo
onitorStat
teException:
current
t thread not owner
r
at java.la
ang.Object
t.wait(Native Meth
hod)
at java.la
ang.Object
t.wait(Object.java
a:474)
at
com.wis
snuwidiarta.thread
d.Sleeping
gBeautyWithWaitAnd
dNotify.ru
un(SleepingB
eautyWi
ithWaitAndNotify.java:24)
at java.la
ang.Thread
d.run(Thread.java:
:595)

Wisnu Widiarta
W

Anda mungkin juga menyukai