Modul 13 Threads
Modul 13 Threads
Pertemuan XIII
THREADS
page 1 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
c. Resumed
Setelah sebelumnya di blok atau diberhentikan sementara, state ini kemudian
siap untuk dijalankan.
d. Suspended
Sebuah thread yang berhenti sementara, dan kemudian memperbolehkan CPU
untuk menjalankan thread lain bekerja.
e. Blocked
Sebuah thread yang di blok merupakan sebuah thread yang tidak mampu
berjalan, karena ia akan menunggu sebuah resource tersedia atau sebuah event
terjadi.
page 2 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
b. Thread(String name)
Membuat sebuah object thread dengan memberikan penamaan yang spesifik.
c. Thread(Runnable target)
Membuat sebuah object Thread yang baru berdasar pada object Runnable.
Target menyatakan sebuah object dimana method run dipanggil.
d. Thread(Runnable target, String name)
Membuat sebuah object Thread yang baru dengan nama yang spesifik dan
berdasarkan pada object Runnable.
e. Thread(ThreadGroup group, Runnable target)
Membuat sebuah object Thread yang baru dalam group.
f. Thread(ThreadGroup group, Runnable target, String name)
Membuat sebuah object Thread yang baru dengan nama yang spesifik dan
berdasarkan pada object Runnable dalam group.
g. Thread(ThreadGroup group, Runnable target, String name, long
stackSize)
Membuat sebuah object Thread yang baru dengan nama yang spesifik dan
berdasarkan pada object Runnable dalam group dengan ukuran stack yang
spesifik.
h. Thread(ThreadGroup group, String name)
Membuat sebuah object thread dengan memberikan penamaan yang spesifik
dalam group.
13.2.2. Constants
Class Thread juga menyediakan beberapa konstanta sebagai nilai prioritas. Berikut
ini adalah rangkuman konstanta dari class Thread.
a. public final static int MAX_PRIORITY
Nilai prioritas maksimum, 10
b. public final static int MIN_PRIORITY
Nilai prioritas minimum, 1.
c. public final static int NORM_PRIORITY
Nilai default prioritas, 5.
13.2.3. Methods
Metode-metode yang disediakan dalam class Thread antara lain :
a. public static Thread currentThread()
Mengembalikan sebuah reference kepada thread yang sedang berjalan.
b. public final String getName()
Mengembalikan nama dari thread.
c. public final void setName(String name)
Mengulang pemberian nama thread sesuai dengan argument name. Hal ini dapat
menyebabkan SecurityException.
d. public final int getPriority()
Mengembalikan nilai integer yang menunjukkan prioritas yang telah diberikan
kepada thread tersebut.
e. public final boolean isAlive()
Mengembalikan nilai Boolean yang menunjukkan bahwa thread tersebut sedang
berjalan atau tidak.
page 3 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
import javax.swing.*;
import java.awt.*;
class CountDownGUI extends JFrame {
JLabel label;
JLabel label2;
CountDownGUI(String title) {
super(title);
label = new JLabel("Start count!");
label2 = new JLabel("Start count!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(new Panel(), BorderLayout.WEST);
getContentPane().add(label);
setSize(300,300);
setVisible(true);
}
void startCount() {
try {
for (int i = 10; i > 0; i--) {
Thread.sleep(1000);
label.setText(i + "");
}
Thread.sleep(1000);
label.setText("Count down complete.");
Thread.sleep(1000);
} catch (InterruptedException ie) {
}
label.setText(Thread.currentThread().toString());
}
page 4 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TestThread {
public static void main(String args[]) {
PrintNameThread pnt1 = new PrintNameThread("A");
PrintNameThread pnt2 = new PrintNameThread("B");
PrintNameThread pnt3 = new PrintNameThread("C");
PrintNameThread pnt4 = new PrintNameThread("D");
}
}
Perhatikan bahwa variable reference pnt1, pnt2, pnt3, dan pnt4 hanya digunakan
satu kali. Untuk aplikasi ini, variabel yang menunjuk pada tiap thread pada dasarnya tidak
dibutuhkan. Kita dapat mengganti body dari main tersebut dengan pernyataan berikut
ini_:
new PrintNameThread("A");
new PrintNameThread("B");
new PrintNameThread("C");
new PrintNameThread("D");
Program akan memberikan keluaran yang berbeda pada setiap eksekusi. Berikut ini
adalah salah satu contoh dari output-nya.
AAAAAAAAAAACCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAACCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDBBBBBBBBBBBBBBBBBBBBDDDDDDDDDDDDDD
page 5 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TestThreadRunnable {
public static void main(String args[]) {
new PrintNameThread("A");
new PrintNameThread("B");
new PrintNameThread("C");
new PrintNameThread("D");
}
}
page 6 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TestThreadJoin {
public static void main(String args[]) {
PrintNameThread pnt1 = new PrintNameThread("A");
PrintNameThread pnt2 = new PrintNameThread("B");
PrintNameThread pnt3 = new PrintNameThread("C");
PrintNameThread pnt4 = new PrintNameThread("D");
System.out.println("Running threads...");
try {
pnt1.thread.join();
pnt2.thread.join();
pnt3.thread.join();
pnt4.thread.join();
} catch (InterruptedException ie) {
}
System.out.println("Threads killed."); //dicetak terakhir
}
}
Cobalah untuk menjalankan program diatas. Apa yang kita dapat? Melalui
pemanggilan method join, kita memastikan bahwa pernyataan terakhir akan dieksekusi
pada saat-saat terakhir.
Sekarang, berilah comment diluar blok try-catch dimana join dipanggil. Apakah ada
perbedaan pada keluarannya?
13.4. Sinkronisasi
Sampai sejauh ini, kita telah melihat contoh-contoh dari thread yang berjalan
bersama-sama tetapi satu dengan yang lainnya tidak bergantung. Thread tersebut adalah
thread yang berjalan sendiri tanpa memperhatikan status dan aktifitas dari thread lain
yang sedang berjalan. Pada contoh tersebut, setiap thread tidak membutuhkan resource
atau method dari luar sehingga ia tidak membutuhkan komunikasi dengan thread lain.
Didalam situasi-situasi tertentu, bagaimanapun sebuah thread yang berjalan
bersama-sama kadang-kadang membutuhkan resource atau method dari luar. Oleh
karena itu, mereka butuh untuk berkomunikasi satu dengan yang lain sehingga dapat
mengetahui status dan aktifitas mereka. Contohnya adalah pada permasalahan produsen-
konsumen.
Kasus ini membutuhkan dua obyek utama, yaitu produsen dan konsumen.
Kewajiban yang dimiliki oleh produsen adalah untuk membangkitkan nilai atau stream
data yang diinginkan oleh konsumen.
class TwoStrings {
static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
page 7 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TestThreadNotSyn {
public static void main(String args[]) {
new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ", "very much!");
}
}
Program ini diharapkan dapat mencetak dua argument obyek Runnable secara
berurutan. Permasalahannya adalah, pendeklarasian metode sleep akan menyebabkan
thread yang lain akan dieksekusi walaupun thread yang pertama belum selesai dijalankan
pada saat eksekusi metode print dari class TwoStrings. Berikut ini adalah contoh dari
keluarannya.
Pada saat berjalan, ketiga thread telah mencetak argument string pertama mereka
sebelum argument kedua dicetak. Sehingga hasilnya adalah sebuah keluaran yang tidak
jelas.
Sebenarnya, pada contoh diatas, tidak menunjukkan permasalahan yang serius.
Akan tetapi pada aplikasi yang lain hal ini dapat menimbulkan exception atau
permasalahan-permasalahan tertentu.
page 8 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
tersebut menjadi anggota. Sintaks untuk mensinkronisasi sebuah obyek adalah sebagai
berikut:
synchronized (<object>) {
//statements yang akan disinkronisasikan
}
Dengan ini, obyek dari metode tersebut hanya dapat dipanggil oleh satu thread
pada satu waktu.
class TwoStrings {
synchronized static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
class TestThreadSyn1 {
public static void main(String args[]) {
new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ", "very much!");
}
}
Hello there.
How are you?
Thank you very much!
page 9 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TwoStrings {
static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
class TestThreadSyn2 {
public static void main(String args[]) {
TwoStrings ts = new TwoStrings();
new PrintStringsThread("Hello ", "there.", ts);
new PrintStringsThread("How are ", "you?", ts);
new PrintStringsThread("Thank you ", "very much!", ts);
}
}
page 10 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
page 11 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class SharedData {
int data;
Producer(SharedData sd) {
this.sd = sd;
new Thread(this, "Producer").start();
}
Consumer(SharedData sd) {
this.sd = sd;
new Thread(this, "Consumer").start();
}
class TestProducerConsumer {
public static void main(String args[]) throws Exception {
SharedData sd = new SharedData();
new Producer(sd);
new Consumer(sd);
}
}
page 12 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
Generate 1
Generate 88
Generate 37
Get 37
Get 37
Get 37
Get 37
Generate 23
Get 23
Get 23
Get 23
Get 23
Get 23
Get 23
Generate 88
Generate 97
Generate 11
Generate 31
Generate 53
Generate 81
Hasil tersebut bukanlah hasil yang kita harapkan. Kita berharap bahwa setiap nilai
yang diproduksi oleh produser dan juga kita akan mengansumsikan bahwa konsumen
akan mendapatkan nilai tersebut. Dibawah ini adalah keluaran yang kita harapkan.
Generate 76
Get 76
Generate 25
Get 25
Generate 34
Get 34
Generate 84
Get 84
Generate 48
Get 48
Generate 29
Get 29
Generate 26
Get 26
Generate 86
Get 86
Generate 65
Get 65
Generate 38
Get 38
Generate 46
Get 46
Untuk memperbaiki kode diatas, kita akan menggunakan metode untuk komunikasi
interthread. Implementasi dibawah ini adalah implementasi dari permasalahan produsen
konsumen dengan menggunakan metode untuk komunikasi interthread.
class SharedData {
int data;
boolean valueSet = false;
synchronized void set(int value) {
page 13 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
class TestProducerConsumer2 {
public static void main(String args[]) throws Exception {
SharedData sd = new SharedData();
new Producer(sd);
new Consumer(sd);
}
}
page 14 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
new Thread(<aRunnableObject>).start();
Dengan kemampuan dari interface yang baru ini, obyek Runnable yang telah
diberikan akan dieksekusi menggunakan kode berikut ini:
<anExecutorObject>.execute(<aRunnableObject>);
page 15 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
Executor interface. Class Executors juga menyediakan factory method untuk memanage
thread pool sederhana.
Berikut ini adalah rangkuman dari beberapa factory methods :
a. public static ExecutorService newCachedThreadPool()
Menciptakan sebuah pool thread yang akan menciptakan thread sesuai yang
dibutuhkan, atau ia akan menggunakan kembali thread yang telah dibangun
sebelumnya, apabila tersedia. Sebuah metode overloading, juga akan
menggunakan obyek ThreadFactory sebagai argument.
b. public static ExecutorService newFixedThreadPool(int
nThreads)
Menciptakan sebuah pool thread yang dapat digunakan kembali untuk
membetulkan sebuah thread yang berada didalam antrian yang tidak teratur.
Sebuah overloading method, akan menggunakan obyek ThreadFactory sebagai
tambahan parameter.
c. public static ScheduledExecutorService
newScheduledThreadPool(int corePoolSize)
Menciptakan sebuah pool thread yang akan menjadwalkan command yang akan
berjalan setelah diberikan sebuah delay, atau untuk mengeksekusi secara
periodic. Sebuah overloading method, akan menggunakan obyek ThreadFactory
sebagai tambahan parameter.
d. public static ExecutorService newSingleThreadExecutor()
Menciptakan sebuah Executor yang digunakan sebagai satu-satunya pelaksana
dari sebuah antrian thread yang tidak teratur. Sebuah overloading method, juga
akan menggunakan obyek ThreadFactory sebagai tambahan parameter.
e. public static ScheduledExecutorService
newSingleThreadScheduledExecutor()
Menciptakan sebuah Executor thread yang akan menjadwalkan command untuk
dijalankan setelah delay tertentu, atau dieksekusi secara periodic. Sebuah
overloading method, juga akan menggunakan object ThreadFactory sebagai
tambahan parameter.
Pada saat sebuah tugas dari Runnable telah dieksekusi dan diselesaikan dengan
kontrol sebuah interface Executor. Untuk memberhentikan thread ini, kita dapat dengan
mudah memanggil metode shutdown dari interface tersebut seperti berikut ini:
executor.shutdown();
page 16 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
b. Method run mewajibkan kita untuk mengecek setiap exception karena overriding
method tidak dapat menggunakan klausa throws.
Interface Callable pada dasarnya adalah sama dengan interface Runnable tanpa
kelemahan-kelemahan yang telah disebutkan diatas. Untuk mendapatkan hasil dari
sebuah pekerjaan yang telah diselesaikan oleh Runnable, kita harus melakukan suatu
teknik untuk mendapatkan hasilnya. Teknik yang paling umum adalah dengan membuat
sebuah instance variable untuk menyimpan hasilnya. Kode dibawah ini akan
menunjukkan bagaimana hal tersebut dilakukan.
import java.util.concurrent.*;
public class MyCallable implements Callable {
public Integer call() throws java.io.IOException {
...
return someValue;
}
}
V adalah sebuah tipe generic yang berarti nilai pengembalian dari pemanggilan
metode tersebut adalah tipe data reference apapun.
Masih ada lagi fitur-fitur concurrency dalam J2SE 5.0. Lihatlah lagi didalam
dokumentasi API untuk mendapatkan informasi lebih detail lagi mengenai fitur-fitur yang
lain.
page 17 of 18
Materi Pemrograman I (Pertemuan XIII) Universitas Pamulang
Referensi:
1. Hariyanto, Bambang, (2007), Esensi-esensi Bahasa Pemrograman Java, Edisi 2,
Informatika Bandung, November 2007.
2. Utomo, Eko Priyo, (2009), Panduan Mudah Mengenal Bahasa Java, Yrama Widya,
Juni 2009.
3. Tim Pengembang JENI, JENI 1-6, Depdiknas, 2007
page 18 of 18