makalah java

22
MAKALAH PEMROGRAMAN JAVA THREAD PEMROGRAMAN JAVA THREAD Oleh: Reni fatimah 1001081025 TK 2 a

Upload: abdillah-luckyboy

Post on 24-Jul-2015

44 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Makalah Java

MAKALAH

PEMROGRAMAN JAVA THREADPEMROGRAMAN JAVA THREAD

Oleh:

Reni fatimah

1001081025

TK 2 a

POLITEKNIK NEGERI PADANG

2012

PEMROGRAMAN JAVA THREADPEMROGRAMAN JAVA THREAD

Page 2: Makalah Java

1.1. PengertianPengertian

Thread merupakan kemampuan yang disediakan oleh Java untuk membuat aplikasiThread merupakan kemampuan yang disediakan oleh Java untuk membuat aplikasi

yang tangguh, karena thread dalam program memiliki fungsi dan tugas tersendiri.yang tangguh, karena thread dalam program memiliki fungsi dan tugas tersendiri.

Dengan adanya thread, dapat membuat program yang lebih efisien dalam halDengan adanya thread, dapat membuat program yang lebih efisien dalam hal

kecepatan maupun penggunaan sumber daya, karena kita dapat membagi proseskecepatan maupun penggunaan sumber daya, karena kita dapat membagi proses

dalam aplikasi kita pada waktu yang sama. Thread umumnya digunakan untukdalam aplikasi kita pada waktu yang sama. Thread umumnya digunakan untuk

pemrograman multitasking, networking, yang melibatkan pengaksesan ke sumberpemrograman multitasking, networking, yang melibatkan pengaksesan ke sumber

daya secara konkuren. Ada dua cara yang bisa digunakan dalam membuat sebuahdaya secara konkuren. Ada dua cara yang bisa digunakan dalam membuat sebuah

thread, yaitu :thread, yaitu :

•• Membuat subclass dari threadMembuat subclass dari thread

Untuk menjalankan thread, dapat dilakukan dengan memanggil method start().Untuk menjalankan thread, dapat dilakukan dengan memanggil method start().

Saat start() dijalankan, maka sebenarnya method run() dari class akanSaat start() dijalankan, maka sebenarnya method run() dari class akan

dijalankan. Jadi untuk membuat thread, harus mendefinisikan method run()dijalankan. Jadi untuk membuat thread, harus mendefinisikan method run()

pada definisi class. Konstruktor dari cara ini adalah :pada definisi class. Konstruktor dari cara ini adalah :

ClassThread namavar = new ClassThread(); Namavar.start();ClassThread namavar = new ClassThread(); Namavar.start();

Atau dapat juga langsung dengan cara:Atau dapat juga langsung dengan cara:

New ClassThread().start();New ClassThread().start();

•• Mengimplementasikan interface RunnableMengimplementasikan interface Runnable

Cara ini merupakan cara yang paling sederhana dalam membuat thread.Cara ini merupakan cara yang paling sederhana dalam membuat thread.

Runnable merupakan unit abstrak, yaitu kelas yang mengimplementasikanRunnable merupakan unit abstrak, yaitu kelas yang mengimplementasikan

interface ini hanya cukup mengimplementasikan fungsi run(). Dalaminterface ini hanya cukup mengimplementasikan fungsi run(). Dalam

mengimplementasi fungsi run(), kita akan mendefinisikan instruksi yangmengimplementasi fungsi run(), kita akan mendefinisikan instruksi yang

membangun sebuah thread. Konstruktor dari cara ini adalah : membangun sebuah thread. Konstruktor dari cara ini adalah :

ObjekRunnable objek = new ObjekRunnable(); ObjekRunnable objek = new ObjekRunnable();

Thread namavar = new Thread(Objek Runnable); Thread namavar = new Thread(Objek Runnable);

Atau dengan cara singkat seperti :Atau dengan cara singkat seperti :

New Thread(new ObjekRunnable());New Thread(new ObjekRunnable());

Daemon Dan User Thread,Daemon Dan User Thread, Ada dua Macam thread dalam Java, yaitu Ada dua Macam thread dalam Java, yaitu

daemon dan user thread. Daemon thread merupakan thread yang siklus hidupnyadaemon dan user thread. Daemon thread merupakan thread yang siklus hidupnya

Page 3: Makalah Java

tergantung pada thread utama atau induk, sehingga apabila thread induk berakhir,tergantung pada thread utama atau induk, sehingga apabila thread induk berakhir,

maka otomatis thread-thread daemon juga ikut berakhir. Sedangkan user threadmaka otomatis thread-thread daemon juga ikut berakhir. Sedangkan user thread

memiliki sifat berbeda, dimana apabila thread utama sudah selesai, maka user threadmemiliki sifat berbeda, dimana apabila thread utama sudah selesai, maka user thread

akan terus dijalankan.akan terus dijalankan.

Sleep,Sleep, Mengatur thread untuk menghentikan prosesnya sejenak dan memberi Mengatur thread untuk menghentikan prosesnya sejenak dan memberi

kesempatan pada thread atau proses lain. Sleep dilakukan dengan cara memanggilkesempatan pada thread atau proses lain. Sleep dilakukan dengan cara memanggil

method : method :

Sleep(long waktu); Waktu untuk method ini merupakan tipe long dalam milisekon. Sleep(long waktu); Waktu untuk method ini merupakan tipe long dalam milisekon.

Interrupt,Interrupt, Apabila menginginkan suatu thread untuk menghentikan proses, Apabila menginginkan suatu thread untuk menghentikan proses,

maka perlu memanggil method interrupt. Interrupt digunakan untuk memberi signalmaka perlu memanggil method interrupt. Interrupt digunakan untuk memberi signal

pada thread untuk menghentikan prosesnya.pada thread untuk menghentikan prosesnya.

Latihan Thread.java Latihan Thread.java

class ThreadBaru extends Thread { class ThreadBaru extends Thread {

public ThreadBaru(String id) {public ThreadBaru(String id) {

super(id); super(id);

start(); //Mulai eksekusi thread barustart(); //Mulai eksekusi thread baru

}}

public void run() { public void run() {

for(int i=0;i<5;i++){ for(int i=0;i<5;i++){

try{try{

Thread.sleep(100);Thread.sleep(100);

}catch(InterruptedException e) {}}catch(InterruptedException e) {}

} }

} }

}}

class DemoThread {class DemoThread {

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

ThreadBaru thread1 = new ThreadBaru("Thread1"); ThreadBaru thread2 = newThreadBaru thread1 = new ThreadBaru("Thread1"); ThreadBaru thread2 = new

ThreadBaru("Thread2"); ThreadBaru thread3 = new ThreadBaru("Thread3");ThreadBaru("Thread2"); ThreadBaru thread3 = new ThreadBaru("Thread3");

System.out.println("Thread1 masih dieksekusi : " + thread1.isAlive());System.out.println("Thread1 masih dieksekusi : " + thread1.isAlive());

System.out.println("Thread2 masih dieksekusi : " + thread2.isAlive());System.out.println("Thread2 masih dieksekusi : " + thread2.isAlive());

System.out.println("Thread3 masih dieksekusi : " + thread3.isAlive()); System.out.println("Thread3 masih dieksekusi : " + thread3.isAlive()); //tunggu//tunggu

hingga semua child thread selesai dieksekusi hingga semua child thread selesai dieksekusi

try{try{

Page 4: Makalah Java

thread1.join(); thread1.join();

System.out.println("Thread1 selesai dieksekusi"); System.out.println("Thread1 selesai dieksekusi");

thread2.join();thread2.join();

System.out.println("Thread2 selesai dieksekusi"); System.out.println("Thread2 selesai dieksekusi");

thread3.join();thread3.join();

System.out.println("Thread3 selesai dieksekusi"); System.out.println("Thread3 selesai dieksekusi");

}catch(InterruptedException e) {}catch(InterruptedException e) {

System.out.println("Thread utama diinterupsi " + e);System.out.println("Thread utama diinterupsi " + e);

}}

System.out.println("Thread utama selesai dieksekusi"); System.out.println("Thread utama selesai dieksekusi");

} }

}}

SynchronizedSynchronized

Sinkronisasi adalah method atau blok yang memiliki tambahan keywordSinkronisasi adalah method atau blok yang memiliki tambahan keyword

synchronized, sehingga apabila dijalankan maka hanya satu thread pada suatu waktusynchronized, sehingga apabila dijalankan maka hanya satu thread pada suatu waktu

yang dapat menjalankan method atau blok program. Thread lain akan menungguyang dapat menjalankan method atau blok program. Thread lain akan menunggu

thread yang sedang mengeksekusi method ini hingga selesai. Mekanisme sinkronisasithread yang sedang mengeksekusi method ini hingga selesai. Mekanisme sinkronisasi

penting apabila terjadi pembagian sumber daya maupun data di antara thread-thread.penting apabila terjadi pembagian sumber daya maupun data di antara thread-thread.

Sinkronisasi juga melakukan penguncian pada sumber daya atau data yang sedangSinkronisasi juga melakukan penguncian pada sumber daya atau data yang sedang

diproses.diproses.

Latihan ThreadSinkronisasi.java Latihan ThreadSinkronisasi.java

class TestSinkronisasi {class TestSinkronisasi {

private java.util.Random random = new java.util.Random(); private java.util.Random random = new java.util.Random();

public void callMe(String data) { public void callMe(String data) {

System.out.print("[");System.out.print("[");

try{ try{

Thread.sleep(random.nextInt(200)); Thread.sleep(random.nextInt(200));

Page 5: Makalah Java

}catch(InterruptedException e) {}catch(InterruptedException e) {

e.printStackTrace(); e.printStackTrace();

}}

System.out.print(data);System.out.print(data);

try{try{

Thread.sleep(random.nextInt(200));Thread.sleep(random.nextInt(200));

}catch(InterruptedException e) {}catch(InterruptedException e) {

e.printStackTrace(); e.printStackTrace();

} System.out.println("]");} System.out.println("]");

}}

}}

class ThreadBaru extends Thread {class ThreadBaru extends Thread {

private String data;private String data;

private TestSinkronisasi obj;private TestSinkronisasi obj;

public ThreadBaru(TestSinkronisasi obj,String data) {public ThreadBaru(TestSinkronisasi obj,String data) {

this.obj = obj; this.obj = obj;

this.data = data;this.data = data;

start(); start();

} public void run() { } public void run() {

obj.callMe(data); obj.callMe(data);

}}

}}

class DemoThread {class DemoThread {

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

TestSinkronisasi obj = new TestSinkronisasi(); TestSinkronisasi obj = new TestSinkronisasi();

ThreadBaru thread1 = new ThreadBaru(obj,"Superman");ThreadBaru thread1 = new ThreadBaru(obj,"Superman");

ThreadBaru thread2 = new ThreadBaru(obj,"Batman"); ThreadBaru thread2 = new ThreadBaru(obj,"Batman");

ThreadBaru thread3 = new ThreadBaru(obj,"Spiderman");ThreadBaru thread3 = new ThreadBaru(obj,"Spiderman");

//tunggu hingga semua child thread selesai dieksekusi //tunggu hingga semua child thread selesai dieksekusi

try{ thread1.join();try{ thread1.join();

thread2.join();thread2.join();

thread3.join();thread3.join();

Page 6: Makalah Java

}catch(InterruptedException e) {}catch(InterruptedException e) {

System.out.println("Thread utama diinterupsi " + e);System.out.println("Thread utama diinterupsi " + e);

}}

}}

}}

Prioritas

Prioritas suatu thread digunakan untuk memberi tahu penjadwal thread tentang

prioritas thread tersebut. Tetap saja urutannya tidak bisa ditentukan karena sifatnya yang non-

deterministik. Jika ada beberapa thread yang sedang diblok dan menunggu giliran untuk

dijalankan, penjadwal thread akan cenderung menjalankan thread dengan prioritas tertinggi

terlebih dahulu. Akan tetapi, tidak berarti thread dengan prioritas rendah tidak akan pernah

dijalankan, hanya lebih jarang dijalankan ketimbang thread dengan prioritas tinggi.

Perhatikan contoh berikut :

package com.lyracc.prioritasthread;

public class PrioritasThread extends Thread {

private int hitungMundur = 5;

private volatile double d = 0; // No optimization

public PrioritasThread(int prioritas) {

setPriority(prioritas);

start();

}

  public void run() {

while (true) {

for(int i = 1; i < 100000; i++)

d = d + (Math.PI + Math.E) / (double)i;

Page 7: Makalah Java

System.out.println(this.toString() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

}

}

/**

* @param args

*/

public static void main(String[] args) {

new PrioritasThread(Thread.MAX_PRIORITY);

for(int i = 0; i < 5; i++)

new PrioritasThread(Thread.MIN_PRIORITY);

}

}

Pada contoh di atas, kita ubah konstruktornya untuk mengeset prioritas kemudian

menjalankan thread. Pada metode main() kita buat 6 thread, yang pertama dengan prioritas

maximum, dan yang lain dengan prioritas minimum. Perhatikan keluarannya, bagaimana

thread pertama dijalankan lebih dulu sedangkan thread-thread lain berjalan seperti biasa

dalam kondisi acak karena memiliki prioritas yang sama.

Di dalam metode run() kita lakukan perhitungan matematika selama 100.000 kali.

Tentunya ini perhitungan yang memakan waktu sehingga setiap thread harus menunggu

giliran di saat thread lain sedang dijalankan. Tanpa perhitungan ini, thread akan dilaksanakan

sangat cepat dan kita tidak bisa melihat efek dari prioritas thread.

Prioritas suatu thread bisa kita set kapan saja (tidak harus pada konstruktor) dengan

metode setPriority(int prioritas) dan kita bisa membaca prioritas suatu thread dengan

menggunakan metode getPriority().

Meskipun JDK memiliki 10 tingkat prioritas, akan tetapi sistem operasi memiliki

tingkat prioritas yang berbeda-beda. Windows misalnya memiliki 7 tingkat dan Solaris

Page 8: Makalah Java

memiliki 231 tingkat prioritas. Yang lebih pasti adalah menggunakan konstanta

MAX_PRIORITY, NORM_PRIORITY, dan MIN_PRIORITY pada kelas thread.

Variasi Kode

Pada contoh-contoh di atas, semua objek thread yang kita buat diturunkan dari kelas

Thread. Kita hanya membuat objek yang berfungsi sebagai thread dan tidak memiliki tugas

dan fungsi lain. Akan tetapi, kelas kita mungkin saja merupakan kelas turunan dari kelas lain.

Karena Java tidak mendukung pewarisan berganda, kita tidak bisa menurunkan kelas tersebut

bersamaan dengan kelas Thread.

Dalam hal ini, kita bisa menggunakan cara alternatif yaitu dengan mengimplementasi

interface Runnable. Runnable hanya memiliki satu metode untuk diimplementasi, yaitu

metode run().

Contoh berikut mendemonstrasikan contoh penggunaannya :

package com.lyracc.runnablesederhana;

public class RunnableSederhana implements Runnable {

private int hitungMundur = 5;

public void run() {

while (true) {

System.out.println(Thread.currentThread().getName() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

}

}

 

public static void main(String[] args) {

for (int i = 1; i <= 5; i++) {

// Buat thread baru dan jalankan

Thread a = new Thread(new RunnableSederhana(), "Thread ke-" + i);

a.start();

}

}

Page 9: Makalah Java

}

Satu-satunya yang dibutuhkan oleh kelas RunnableSederhana adalah metode run(),

akan tetapi jika kita ingin melakukan hal lainnya, seperti getName(), sleep(), dan lainnya, kita

harus secara eksplisit memberikan referensi dengan menggunakan Thread.currentThread().

Ketika suatu kelas mengimplementasikan interface Runnable, artinya kelas ini

memiliki metode bernama run(), akan tetapi tidak berarti bahwa kelas ini bisa melakukan

sesuatu seperti kelas Thread atau kelas-kelas turunan yang kita buat dari kelas ini. Kita harus

membuat objek Thread sendiri seperti ditunjukkan dalam metode main() di atas, kemudian

menjalankan start() sendiri.

Kemudahan yang ditawarkan oleh interface Runnable adalah kemungkinan untuk

menggabungkannya dengan kelas dan interface lain. Misalnya kita ingin membuat kelas baru

yang merupakan kelas turunan dari suatu kelas lain. Kita cukup menambahkan impement

Runnable pada definisi kelasnya untuk membuat kelas yang bisa kita jadikan thread. Dengan

cara ini, kita masih bisa mengakses anggota kelas induk secara langsung, tanpa melalui objek

lain. Akan tetapi, kelas dalam (inner class) juga bisa mengakses anggota kelas luar (outer

class). Kadang-kadang kita ingin juga membuat kelas dalam yang merupakan turunan dari

kelas Thread.

Perhatikan beberapa variasi untuk mendeklarasikan dan menggunakan thread pada contoh

berikut ini.

package com.lyracc.variasithread;

// Kelas dalam bernama

class KelasDalamBernama {

private int hitungMundur = 5;

private Dalam dalam;

// Kelas Dalam adalah kelas dalam (inner class) yang

// merupakan kelas turunan kelas Thread

private class Dalam extends Thread {

Dalam(String nama) {

super(nama);

start();

Page 10: Makalah Java

}

 

public void run() {

while (true) {

System.out.println(getName() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

try {

sleep(10);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

}

}

// akhir Dalam

// Konstruktor KelasDalamBernama

// Membuat objek baru yang merupakan instansi kelas Dalam

public KelasDalamBernama(String nama) {

dalam = new Dalam(nama);

}

}

// akhir KelasDalamBernama

// Kelas dalam anonim

class KelasDalamAnonim {

private int hitungMundur = 5;

private Thread t;

// Konstruktor KelasDalamAnonim

public KelasDalamAnonim(String nama) {

// Kelas anonim turunan Thread

t = new Thread(nama) {

public void run() {

while (true) {

System.out.println(getName() + " : " + hitungMundur);

Page 11: Makalah Java

if (--hitungMundur == 0)

return;

try {

sleep(10);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

}

}; // akhir kelas anonim

t.start();

}

}

// akhir KelasDalamAnonim

// Kelas dalam implementasi runnable bernama

class KelasRunnableBernama {

private int hitungMundur = 5;

private Dalam dalam;

// Kelas Dalam adalah kelas dalam (inner class) yang

// merupakan kelas yang mengimplementasi Runnable

private class Dalam implements Runnable {

Thread t;

Dalam(String nama) {

t = new Thread(this, nama);

t.start();

}

public void run() {

while (true) {

System.out.println(t.getName() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

try {

Thread.sleep(10);

} catch (InterruptedException e) {

Page 12: Makalah Java

throw new RuntimeException(e);

}

}

}

} // akhir kelas Dalam

 

// Konstruktor KelasRunnableBernama

// Membuat objek baru yang merupakan instansi kelas Dalam

public KelasRunnableBernama(String nama) {

dalam = new Dalam(nama);

}

} // akhir KelasRunnableBernama

 

// Kelas dalam implementasi runnable anonim

class KelasRunnableAnonim {

private int hitungMundur = 5;

private Thread t;

public KelasRunnableAnonim(String nama) {

t = new Thread(new Runnable() {

public void run() {

while (true) {

System.out.println(Thread.currentThread().getName() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

try {

Thread.sleep(10);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

}

 

}, nama); // akhir kelas dalam anonim

t.start();

Page 13: Makalah Java

}

} // akhir KelasRunnableAnonim

 

// Menjalankan thread dari dalam metode dan kelas anonim

class ThreadViaMetode {

private int hitungMundur = 5;

private Thread t;

private String nama;

 

public ThreadViaMetode(String nama) {

this.nama = nama;

}

 

public void runThread() {

if (t == null) {

// Definisi kelas anonim dari dalam metode

t = new Thread(nama) {

public void run() {

while (true) {

System.out.println(getName() + " : " + hitungMundur);

if (--hitungMundur == 0)

return;

try {

sleep(10);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

}

}; // akhir kelas dalam anonim

t.start();

}

}

} // akhir ThreadViaMetode

Page 14: Makalah Java

 

public class VariasiThread {

public static void main(String[] args) {

new KelasDalamBernama("KelasDalamBernama");

new KelasDalamAnonim("KelasDalamAnonim");

new KelasRunnableBernama("KelasRunnableBernama");

new KelasRunnableAnonim("KelasRunnableAnonim");

new ThreadViaMetode("ThreadViaMetode").runThread();

}

}

Jika kita menggunakan Runnable, pada dasarnya kita menyatakan bahwa kita ingin

membuat suatu proses -- yang implementasinya berada di dalam metode run() -- bukan suatu

objek yang melakukan proses tertentu. Tentunya hal ini tergantung dari cara pandang kita,

apakah kita ingin menganggap suatu thread sebagai objek atau sesuatu yang sama sekali

berbeda, yaitu proses.

Jika kita menganggap suatu thread sebagai proses, tetntunya kita akan terbebas dari

cara pandang berorientasi objek yaitu "semuanya adalah objek". Artinya juga, kita tidak perlu

membuat seluruh kelas menjadi Runnable jika hanya kita ingin memulai proses di bagian

tertentu program kita. Karenanya, mungkin lebih masuk akal untuk menyembunyikan thread

di dalam kelas kita menggunakan kelas dalam.

KelasDalamBernama[.code] membuat kelas dalam yang merupakan kelas turunan

dari kelas Thread, dan membuat instansi kelas ini di dalam konstruktornya. Cara ini baik jika

kita ingin kelas dalam tersebut memiliki suatu kemampuan tertentu (metode lain) yang ingin

kita gunakan. Akan tetapi, seringkali kita membuat thread hanya untuk memanfaatkan

[code]Thread saja, artinya kita mungkin tidak perlu membuat kelas yang memiliki nama.

KelasDalamAnonim adalah alternatif dari KelasDalamBernama di mana kelas

dalamnya merupakan kelas anonim yang merupakan kelas turunan dari kelas Thread. Kelas

anonim ini dibuat di dalam konstruktor dan disimpan dalam bentuk referensi t bertipe Thread.

Jika metode kelas lain membutuhkan akses ke t, maka kita bisa menggunakannya seperti

Thread biasa tanpa perlu mengetahui tipe objek t sesungguhnya.

Page 15: Makalah Java

Kelas ketiga dan keempat pada contoh di atas mirip dengan contoh pertama dan

kedua, akan tetapi menggunakan interface Runnable. Contoh ini hanya ingin menunjukkan

bahwa menggunakan Runnable tidak menambah nilai apa-apa, kecuali membuat kodenya

lebih sulit dibaca. Kelas ThreadViaMetode menunjukkan bagaimana membuat thread dari

dalam metode. Kita bisa memanggil metode tersebut jika kita siap untuk menjalankan thread

ini. Metode ini akan selesai setelah thread berjalan. Jika thread hanya melakukan tugas

sampingan, mungkin cara ini lebih cocok daripada mengimplementasikan kelas khusus untuk

melakukan fungsi-fungsi thread.

Page 16: Makalah Java

CONTOH LAIN PROGRAM JAVA THREAD

Program Countdown Menggunakan Thread Pada Java

public class CountDown implements Runnable{private static int startCount = 11;private int countDown = --startCount;private static int threadCount = 0;private int threadNumber = ++threadCount;public void run() { System.out.println("Waktu tinggal "+countDown+" detik ( Thread nomer : "+threadNumber+" )");if (countDown == 1) {

System.out.println("\nWaktu Habis ~ !!"); } }

private static void doThreadCountdown() throws java.lang.InterruptedException{for (int i = 0; i < 10; i++){Thread.sleep(1000);Runnable ot = new CountDown();Thread th = new Thread(ot);th.start(); }}

public static void main(String[] args) throws java.lang.InterruptedException{ System.out.println("\nMenghitung mundur dalam 10 detik ...\n"); doThreadCountdown(); } }

Penjelasan : Pada program ini menghasilkan 10 buah thread dengan menggunakan

looping sebanyak 10 kali dan setiap thread yang tercipta dimanfaatkan untuk melakukan

hitung mundur/countdown.

REFERENSI

Ady Wicaksono, Dasar – Dasar Pemrograman Java 2, Penerbit PT Elex Media

Komputindo, Jakarta, 2002.

Benny Hermawan, Menguasai JAVA 2 Object Oriented Programming, Penerbit ANDI

Yogyakarta, Yogyakarta, 2004.

Page 17: Makalah Java

Ginanjar Utama, Berfikir Objek:Cara Efektif Menguasai Java, 2003,

http://ilmukomputer.com/berseri/ginanjar-java/index.php (26 Desember 2004).

Indrajani dan Martin, Pemrograman Berorientasi Objek dengan Java, Penerbit PT

Elex Media Komputindo, Jakarta, 2004.

Isak Rickyanto, Dasar Pemrograman Berorientasi Objek dengan Java 2 (JDK1.4),

Penerbit ANDI Yogyakarta, Yogyakarta, 2003.

http://nolimitz.web.id/2010/03/program-countdown-menggunakan-thread-pada-java/

http://java.lyracc.com/belajar/java-untuk-pemula/dasar-dasar-thread