Class Thread Java
Class Thread Java
2.1 Tujuan:
Setelah mempelajari modul ini peserta diharapkan dapat:
• Mengenal Kelas Thread
• Menggunakan Kelas Thread dalam aplikasi
1. Thread Synchronization.
2. Interthread Communication.
3. Thread Deadlock.
4. Thread Control
Berikut adalah contoh sederhana yang mungkin atau mungkin tidak mencetak nilai counter
secara berurutan dan setiap kali kita menjalankannya, itu menghasilkan hasil yang berbeda
berdasarkan ketersediaan CPU untuk sebuah thread. Dapat melihat contoh kode dibawah
untuk lebih jelasnya
1
class PrintDemo {
2
public void printCount() {
3
try {
4
for(int i = 5; i > 0; i--) {
5
System.out.println("Counter --- " + i );
6
}
7
} catch (Exception e) {
8
System.out.println("Thread interrupted.");
9
}
10
}
11
}
12
13
class ThreadDemo extends Thread {
14
private Thread t;
15
private String threadName;
16
PrintDemo PD;
17
18
ThreadDemo( String name, PrintDemo pd) {
19
threadName = name;
20
PD = pd;
21
}
22
23
public void run() {
24
PD.printCount();
25
System.out.println("Thread " + threadName + " exiting.");
26
}
27
28
public void start () {
29
System.out.println("Starting " + threadName );
30
if (t == null) {
31
t = new Thread (this, threadName);
32
t.start ();
33
}
34
}
35
}
36
37
public class TestThread {
38
public static void main(String args[]) {
39
40
PrintDemo PD = new PrintDemo();
41
42
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
43
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );
44
45
T1.start();
46
T2.start();
47
48
// wait for threads to end
49
try {
50
T1.join();
51
T2.join();
52
} catch ( Exception e) {
53
System.out.println("Interrupted");
54
}
55
}
56
}
Ini menghasilkan hasil yang berbeda setiap kali Anda menjalankan program ini yaitu
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 5
Counter --- 2
Counter --- 1
Counter --- 4
Thread Thread - 1 exiting.
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 2 exiting.
1
class PrintDemo {
2
public void printCount() {
3
try {
4
for(int i = 5; i > 0; i--) {
5
System.out.println("Counter --- " + i );
6
}
7
} catch (Exception e) {
8
System.out.println("Thread interrupted.");
9
}
10
}
11
}
12
13
class ThreadDemo extends Thread {
14
private Thread t;
15
private String threadName;
16
PrintDemo PD;
17
18
ThreadDemo( String name, PrintDemo pd) {
19
threadName = name;
20
PD = pd;
21
}
22
23
public void run() {
24
synchronized(PD) {
25
PD.printCount();
26
}
27
System.out.println("Thread " + threadName + " exiting.");
28
}
29
30
public void start () {
31
System.out.println("Starting " + threadName );
32
if (t == null) {
33
t = new Thread (this, threadName);
34
t.start ();
35
}
36
}
37
}
38
39
public class TestThread {
40
41
public static void main(String args[]) {
42
PrintDemo PD = new PrintDemo();
43
44
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
45
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );
46
47
T1.start();
48
T2.start();
49
50
// wait for threads to end
51
try {
52
T1.join();
53
T2.join();
54
} catch ( Exception e) {
55
System.out.println("Interrupted");
56
}
57
}
58
}
Ini menghasilkan hasil yang sama setiap kali Anda menjalankan program ini yaitu
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 1 exiting.
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 2 exiting.
Interthread Communication
Jika Anda mengetahui komunikasi antarproses maka akan mudah bagi Anda untuk
memahami komunikasi interthread. Komunikasi interthread penting ketika Anda
mengembangkan aplikasi di mana dua atau lebih utas bertukar beberapa informasi.
Ada tiga metode sederhana dan sedikit trik yang memungkinkan komunikasi utas. Ketiga
metode tersebut tercantum di bawah ini yaitu
public void wait () yaitu Menyebabkan utas saat ini menunggu hingga thread lain untuk
memanggil notify ().
public void notify () yaitu Membangunkan satu thread yang menunggu di monitor pada
objek ini.
public void notifyAll () yaitu Membangunkan semua thread yang memanggil wait () pada
objek yang sama.
Metode ini telah diimplementasikan sebagai metode terakhir di Object, sehingga tersedia di
semua kelas. Ketiga metode hanya dapat dipanggil dari dalam konteks yang disinkronkan.
Contoh ini menunjukkan bagaimana dua thread dapat berkomunikasi menggunakan metode
wait () dan notify (). Anda dapat membuat sistem yang kompleks dengan menggunakan
konsep yang sama. Contohnya dapat dilihat pada kode berikut
1
class Chat {
2
boolean flag = false;
3
4
public synchronized void Question(String msg) {
5
if (flag) {
6
try {
7
wait();
8
} catch (InterruptedException e) {
9
e.printStackTrace();
10
}
11
}
12
System.out.println(msg);
13
flag = true;
14
notify();
15
}
16
17
public synchronized void Answer(String msg) {
18
if (!flag) {
19
try {
20
wait();
21
} catch (InterruptedException e) {
22
e.printStackTrace();
23
}
24
}
25
26
System.out.println(msg);
27
flag = false;
28
notify();
29
}
30
}
31
32
class T1 implements Runnable {
33
Chat m;
34
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };
35
36
public T1(Chat m1) {
37
this.m = m1;
38
new Thread(this, "Question").start();
39
}
40
41
public void run() {
42
for (int i = 0; i < s1.length; i++) {
43
m.Question(s1[i]);
44
}
45
}
46
}
47
48
class T2 implements Runnable {
49
Chat m;
50
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
51
52
public T2(Chat m2) {
53
this.m = m2;
54
new Thread(this, "Answer").start();
55
}
56
57
public void run() {
58
for (int i = 0; i < s2.length; i++) {
59
m.Answer(s2[i]);
60
}
61
}
62
}
63
public class TestThread {
64
public static void main(String[] args) {
65
Chat m = new Chat();
66
new T1(m);
67
new T2(m);
68
}
69
}
Ketika program di atas dipenuhi dan dijalankan, itu menghasilkan hasil sebagai berikut
Hi
Hi
How are you ?
I am good, what about you?
I am also doing fine!
Great!
Thread Deadlock
Deadlock menggambarkan situasi di mana dua atau lebih utas diblokir selamanya, menunggu
satu sama lain. Kebuntuan terjadi ketika beberapa utas membutuhkan kunci yang sama tetapi
mendapatkannya dalam urutan yang berbeda. Program multithread Java mungkin mengalami
kondisi kebuntuan karena kata kunci tersinkronisasi menyebabkan thread yang menjalankan
memblokir saat menunggu kunci, atau monitor, yang terkait dengan objek tertentu. Berikut
1
public class TestThread {
2
public static Object Lock1 = new Object();
3
public static Object Lock2 = new Object();
4
5
public static void main(String args[]) {
6
ThreadDemo1 T1 = new ThreadDemo1();
7
ThreadDemo2 T2 = new ThreadDemo2();
8
T1.start();
9
T2.start();
10
}
11
12
private static class ThreadDemo1 extends Thread {
13
public void run() {
14
synchronized (Lock1) {
15
System.out.println("Thread 1: Holding lock 1...");
16
17
try { Thread.sleep(10); }
18
catch (InterruptedException e) {}
19
System.out.println("Thread 1: Waiting for lock 2...");
20
21
synchronized (Lock2) {
22
System.out.println("Thread 1: Holding lock 1 & 2...");
23
}
24
}
25
}
26
}
27
private static class ThreadDemo2 extends Thread {
28
public void run() {
29
synchronized (Lock2) {
30
System.out.println("Thread 2: Holding lock 2...");
31
32
try { Thread.sleep(10); }
33
catch (InterruptedException e) {}
34
System.out.println("Thread 2: Waiting for lock 1...");
35
36
synchronized (Lock1) {
37
System.out.println("Thread 2: Holding lock 1 & 2...");
38
}
39
}
40
}
41
}
42
}
Ketika Anda mengkompilasi dan menjalankan program di atas, Anda menemukan situasi
kebuntuan dan berikut adalah keluaran yang dihasilkan oleh program
Mari kita ubah urutan kunci dan menjalankan program yang sama untuk melihat apakah
kedua utas masih menunggu satu sama lain. Berikut merupakan contoh kode yang dapat
1
public class TestThread {
2
public static Object Lock1 = new Object();
3
public static Object Lock2 = new Object();
4
5
public static void main(String args[]) {
6
ThreadDemo1 T1 = new ThreadDemo1();
7
ThreadDemo2 T2 = new ThreadDemo2();
8
T1.start();
9
T2.start();
10
}
11
12
private static class ThreadDemo1 extends Thread {
13
public void run() {
14
synchronized (Lock1) {
15
System.out.println("Thread 1: Holding lock 1...");
16
17
try {
18
Thread.sleep(10);
19
} catch (InterruptedException e) {}
20
System.out.println("Thread 1: Waiting for lock 2...");
21
22
synchronized (Lock2) {
23
System.out.println("Thread 1: Holding lock 1 & 2...");
24
}
25
}
26
}
27
}
28
private static class ThreadDemo2 extends Thread {
29
public void run() {
30
synchronized (Lock1) {
31
System.out.println("Thread 2: Holding lock 1...");
32
33
try {
34
Thread.sleep(10);
35
} catch (InterruptedException e) {}
36
System.out.println("Thread 2: Waiting for lock 2...");
37
38
synchronized (Lock2) {
39
System.out.println("Thread 2: Holding lock 1 & 2...");
40
}
41
}
42
}
43
}
44
}
Jadi hanya mengubah urutan kunci mencegah program mengalami situasi kebuntuan dan
selesai dengan hasil sebagai berikut
Thread Control
Core Java menyediakan kendali penuh atas program multithread. Anda dapat
mengembangkan program multithread yang dapat ditangguhkan, dilanjutkan, atau dihentikan
sepenuhnya berdasarkan kebutuhan Anda. Ada berbagai metode statis yang dapat Anda
gunakan pada objek thread untuk mengontrol perilakunya. Berikut ini mencantumkan metode
tersebut yaitu
public void suspend () yaitu Metode ini menempatkan utas dalam status ditangguhkan dan
dapat dilanjutkan menggunakan metode resume ().
public void stop () yaitu Metode ini menghentikan utas sepenuhnya.
resume public void () yaitu Metode ini melanjutkan utas, yang ditangguhkan menggunakan
metode suspend ().
public void wait () yaitu Menyebabkan utas saat ini menunggu hingga utas lain memanggil
metode notify ().
public void notify () yaitu Membangunkan satu utas yang menunggu di monitor objek ini.
Ketahuilah bahwa versi terbaru Java tidak lagi menggunakan metode suspend (), resume (),
dan stop () sehingga Anda perlu menggunakan alternatif yang tersedia. Berikut ini kita dapat
membuat thread control dengan menuliskan kode berikut
1
class RunnableDemo implements Runnable {
2
public Thread t;
3
private String threadName;
4
boolean suspended = false;
5
6
RunnableDemo( String name) {
7
threadName = name;
8
System.out.println("Creating " + threadName );
9
}
10
11
public void run() {
12
System.out.println("Running " + threadName );
13
try {
14
for(int i = 10; i > 0; i--) {
15
System.out.println("Thread: " + threadName + ", " + i);
16
// Let the thread sleep for a while.
17
Thread.sleep(300);
18
synchronized(this) {
19
while(suspended) {
20
wait();
21
}
22
}
23
}
24
} catch (InterruptedException e) {
25
System.out.println("Thread " + threadName + " interrupted.");
26
}
27
System.out.println("Thread " + threadName + " exiting.");
28
}
29
30
public void start () {
31
System.out.println("Starting " + threadName );
32
if (t == null) {
33
t = new Thread (this, threadName);
34
t.start ();
35
}
36
}
37
38
void suspend() {
39
suspended = true;
40
}
41
42
synchronized void resume() {
43
suspended = false;
44
notify();
45
}
46
}
47
48
public class TestThread {
49
50
public static void main(String args[]) {
51
52
RunnableDemo R1 = new RunnableDemo( "Thread-1");
53
R1.start();
54
55
RunnableDemo R2 = new RunnableDemo( "Thread-2");
56
R2.start();
57
58
try {
59
Thread.sleep(1000);
60
R1.suspend();
61
System.out.println("Suspending First Thread");
62
Thread.sleep(1000);
63
R1.resume();
64
System.out.println("Resuming First Thread");
65
66
R2.suspend();
67
System.out.println("Suspending thread Two");
68
Thread.sleep(1000);
69
R2.resume();
70
System.out.println("Resuming thread Two");
71
} catch (InterruptedException e) {
72
System.out.println("Main thread Interrupted");
73
}try {
74
System.out.println("Waiting for threads to finish.");
75
R1.t.join();
76
R2.t.join();
77
} catch (InterruptedException e) {
78
System.out.println("Main thread Interrupted");
79
}
80
System.out.println("Main thread exiting.");
81
}
82
}
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 10
Running Thread-2
Thread: Thread-2, 10
Thread: Thread-1, 9
Thread: Thread-2, 9
Thread: Thread-1, 8
Thread: Thread-2, 8
Thread: Thread-1, 7
Thread: Thread-2, 7
Suspending First Thread
Thread: Thread-2, 6
Thread: Thread-2, 5
Thread: Thread-2, 4
Resuming First Thread
Suspending thread Two
Thread: Thread-1, 6
Thread: Thread-1, 5
Thread: Thread-1, 4
Thread: Thread-1, 3
Resuming thread Two
Thread: Thread-2, 3
Waiting for threads to finish.
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Main thread exiting.