Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Thread
Pengenalan Pemrograman 2
Versi 2.0
Topik
Pengertian Thread
Dasar-dasar Thread
◦ State dari Thread
◦ Prioritas
Class Thread
◦ Constructor
◦ Constants
◦ Method
Topik
Membuat Threads
◦ Menurunkan Class (Extend) Thread
◦ Meng-implementasikan Interface Runnable
◦ Extend vs. Implement
Sinkronisasi
◦ Mengunci Object
Komunikasi Antar Thread (Interthread)
Kemampuan Concurrency
Threads
Mengapa menggunakan threads?
◦ Dibutuhkan untuk mengatasi aliran proses
Pengertian
◦ Merupakan sebuah pengontrol aliran program
◦ Untuk lebih mudahnya, bayangkanlah threads
sebagai proses yang dieksekusi oleh sebuah
program
◦ Contoh:
Operating System
HotJava web browser
Threads
State dari Thread
Sebuah thread memungkinkan untuk memiliki beberapa state :
1.Running
Thread yang sedang dieksekusi
Didalam control dari CPU
2.Ready to run
Siap untuk dieksekusi tetapi belum ada kesempatan
untuk melakukannya
3.Resumed
Siap dijalankan setelah diberhentikan sementara atau
diblok
4.Suspended
Thread yang berhenti sementara, dan kemudian
memperbolehkan CPU untuk menjalankan thread lain
bekerja
5.Blocked
Menunggu sebuah resource tersedia atau sebuah event
Prioritas Thread
Mengapa menggunakan prioritas?
◦ Menentukan thread mana yang akan menerima control dari CPU
dan akan dieksekusi pertama kali
Pengertian:
◦ Nilai integer dari angka 1 sampai dengan 10
◦ Prioritas thread paling tinggi→ semakin besar kesempatan
untuk dieksekusi terlebih dahulu
◦ Contoh:
Dua threads siap untuk dijalankan
Thread pertama: prioritas nomor 5, telah
dijalankan
Thread kedua: prioritas nomor 10, dijalankan
ketika thread pertama sedang dijalankan
Prioritas Thread
Context switch
◦ Terjadi apabila sebagian dari thread telah dikontrol oleh CPU dari
thread yang lain
◦ Ketika switch terjadi?
prioritas tertinggi dari thread adalah thread yang
siap untuk menerima kontrol dari CPU
Pada saat sebuah thread yang sedang berjalan
diambil alih oleh thread yang memiliki prioritas
tertinggi
Lebih dari satu prioritas thread yang siap untuk dijalankan
◦ Menentukan prioritas untuk menerima kontrol dari CPU
bergantung pada sistem operasi
◦ Windows 95/98/NT: Menggunakan time-sliced dan round-robin
◦ Solaris: Membiarkan CPU untuk mengontrol thread yang lain
Class Thread : Constructor
Memiliki delapan constructor
Thread Constructors
Thread()
Membuat sebuah object Thread yang baru.
Thread(String name)
Membuat sebuah object thread dengan memberikan penamaan
yang spesifik.
Thread(Runnable target)
Membuat sebuah object Thread yang baru berdasar pada object
Runnable. Target menyatakan sebuah object dimana method run
dipanggil.
Thread(Runnable target, String name)
Membuat sebuah object Thread yang baru dengan nama yang
spesifik dan berdasarkan pada object Runnable.
Class Thread : Constants
Berisi field untuk nilai prioritas
Thread Constants
public final static int MAX_PRIORITY
Nilai prioritas maksimum, 10
public final static int MIN_PRIORITY
Nilai prioritas minimum, 1.
public final static int NORM_PRIORITY
Nilai default prioritas, 5.
Class Thread : Methods
Beberapa method Thread
Thread Methods
public static Thread currentThread()
Mengembalikan sebuah reference kepada thread yang sedang
berjalan.
public final String getName()
Mengembalikan nama dari thread.
public final void setName(String name)
Mengulang pemberian nama thread sesuai dengan argument
name. Hal ini dapat menyebabkan SecurityException.
public final int getPriority()
Mengembalikan nilai prioritas yang telah diberikan kepada thread
tersebut.
public final boolean isAlive()
Menunjukkan bahwa thread tersebut sedang berjalan atau tidak.
Contoh Sebuah Thread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import javax.swing.*;
import java.awt.*;
class CountDownGUI extends JFrame {
JLabel label;
CountDownGUI(String title) {
super(title);
label = new JLabel("Start count!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(new Panel(),orderLayout.WEST);
getContentPane().add(label);
setSize(300,300);
setVisible(true);
}
//bersambung...
Contoh Sebuah Thread
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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());
}
//bersambung...
Contoh Sebuah Thread
public static void main(String args[])
29
{
CountDownGUI cdg =
31
new CountDownGUI("Count
down GUI");
32
cdg.startCount();
33
}
34 }
30
Membuat Threads
Dua cara dalam membuat threads:
◦ Menurunkan Class Thread
◦ Mengimplementasikan interface Runnable
Membuat turunan
Class Thread
1
2
3
4
5
6
7
8
9
10
11
12
13
class PrintNameThread extends Thread {
PrintNameThread(String name) {
super(name);
start();
//runs the thread once instantiated
}
public void run() {
String name = getName();
for (int i = 0; i < 100; i++) {
System.out.print(name);
}
}
}
//bersambung
Membuat turunan
Class Thread
14 class
15
16
17
18
19
20
21
22
23
24
25 }
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");
}
Membuat turunan
Class Thread
Dapat memodifikasi method main seperti
berikut ini:
14.class
TestThread {
15.
public static void main(String
args[]) {
16.
new PrintNameThread("A");
17.
new PrintNameThread("B");
18.
new PrintNameThread("C");
19.
new PrintNameThread("D");
20.
}
21.}
Membuat turunan
Class Thread
Contoh hasil:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAABCDABCDABCDABCDABCDABCDABCDABCDABCDA
BCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABC
DABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDAB
CDABCDABCDABCDABCDABCDABCDABCDABCDBCDBCDBCD
BCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDB
CDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBC
DBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCDBCD
BCDBCDBCDBCD
Mengimplementasikan
Interface Runnable
Hanya membutuhkan implementasi dari method run
◦ Bayangkanlah bahwa method run adalah method utama dari
thread yang diciptakan
Contoh:
1 class TestThread {
2
public static void main(String args[]) {
3
new PrintNameThread("A");
4
new PrintNameThread("B");
5
new PrintNameThread("C");
6
new PrintNameThread("D");
7
}
8 }
9 //bersambung...
Mengimplementasikan
Interface Runnable
10.class
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.}
PrintNameThread implements Runnable {
Thread thread;
PrintNameThread(String name) {
thread = new Thread(this, name);
thread.start();
}
public void run() {
String name = thread.getName();
for (int i = 0; i < 100; i++) {
System.out.print(name);
}
}
Extend vs. Implement
Memilih salah satu dari kedua cara tersebut
bukanlah sebuah permasalahan
Implementasi interface Runnable
◦ Menyebabkan lebih banyak pekerjaan karena kita harus
Mendeklarasikan sebuah object Thread
Memanggil method Thread pada object itu
◦ Class Anda tetap dapat menjadi turunan dari class lain
Menurunkan class Thread
◦ Lebih mudah untuk diimplementasikan
◦ Class Anda tidak dapat menjadi turunan dari class yang
lainnya
Contoh: Method join
Menyebabkan thread yang sedang bekerja saat ini menungggu
sampai thread yang memanggil method ini selesai dieksekusi
Contoh:
1 class PrintNameThread implements Runnable {
2
Thread thread;
3
PrintNameThread(String name) {
4
thread = new Thread(this, name);
5
thread.start();
6
}
7 //bersambung
Contoh: Method join
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void run() {
String name = thread.getName();
for (int i = 0; i < 100; i++) {
System.out.print(name);
}
}
}
class TestThread {
public static void
PrintNameThread
PrintNameThread
PrintNameThread
PrintNameThread
//bersambung...
main(String args[]) {
pnt1 = new PrintNameThread("A");
pnt2 = new PrintNameThread("B");
pnt3 = new PrintNameThread("C");
pnt4 = new PrintNameThread("D");
Contoh: Method join
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.");
22
23
24
25
26
27
28
29
30
31
32
33
}
}
//mencoba untuk menghilangkan block catch yang ada
Sinkronisasi
Mengapa menggunakan sinkronisasi
threads?
◦ 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
Sebuah contoh yang tidak
disinkronisasi
1
2
3
4
5
6
7
8
9
10
11
class TwoStrings {
static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
//bersambung...
Sebuah contoh yang tidak
disinkronisasi
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class PrintStringsThread implements Runnable {
Thread thread;
String str1, str2;
PrintStringsThread(String str1, String str2) {
this.str1 = str1;
this.str2 = str2;
thread = new Thread(this);
thread.start();
}
public void run() {
TwoStrings.print(str1, str2);
}
}
//bersambung...
Sebuah contoh yang tidak
disinkronisasi
26
27
28
29
30
31
32
33
class TestThread {
public static void main(String args[]) {
new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ",
"very much!");
}
}
Sebuah contoh yang tidak
disinkronisasi
Contoh hasil:
Hello How are Thank you there.
you?
very much!
Sinkronisasi:
Mengunci sebuah Object
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
Object tersebut akan menjalankan sebuah monitor
implicit pada saat object dari method sinkronisasi
dipanggil
Sekali object tersebut dimonitor, monitor tersebut
akan memastikan bahwa tidak ada thread yang
akan mengakses object yang sama
Sinkronisasi:
Mengunci sebuah Object
Sinkronisasi sebuah method:
◦ Menggunakan keyword synchronized
Dapat menjadi header dari pendefinisian method
Dapat mensinkronisasi object dimana method
tersebut menjadi anggota dari
synchronized (<object>) {
//statements yang akan disinkronisasikan
}
Contoh Synchronized Pertama
1
2
3
4
5
6
7
8
9
10
11
12
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);
}
}
//bersambung...
Contoh Synchronized Pertama
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class PrintStringsThread implements Runnable {
Thread thread;
String str1, str2;
PrintStringsThread(String str1, String str2) {
this.str1 = str1;
this.str2 = str2;
thread = new Thread(this);
thread.start();
}
public void run() {
TwoStrings.print(str1, str2);
}
}
//bersambung...
Contoh Synchronized Pertama
27
28
29
30
31
32
33
34
class TestThread {
public static void main(String args[]) {
new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ",
"very much!");
}
}
Contoh Synchronized Pertama
Contoh Hasil:
Hello there.
How are you?
Thank you very much!
Contoh Synchronized Kedua
1
2
3
4
5
6
7
8
9
10
11
class TwoStrings {
static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
//bersambung...
Contoh Synchronized Kedua
12
13
14
15
16
17
18
19
20
21
22
23
24
class PrintStringsThread implements Runnable {
Thread thread;
String str1, str2;
TwoStrings ts;
PrintStringsThread(String str1, String str2,
TwoStrings ts) {
this.str1 = str1;
this.str2 = str2;
this.ts = ts;
thread = new Thread(this);
thread.start();
}
//bersambung...
Contoh Synchronized Kedua
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public void run() {
synchronized (ts) {
ts.print(str1, str2);
}
}
}
class TestThread {
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);
}}
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.
Komunikasi Antar Thread
Contoh Produsen-Konsumen
1
2
3
4
5
6
7
8
9
10
11
12
class SharedData {
int data;
synchronized void set(int value) {
System.out.println("Generate " + value);
data = value;
}
synchronized int get() {
System.out.println("Get " + data);
return data;
}
}
//bersambung...
Contoh Produsen-Konsumen
13
14
15
16
17
18
19
20
21
22
23
24
25
class Producer implements Runnable {
SharedData sd;
Producer(SharedData sd) {
this.sd = sd;
new Thread(this, "Producer").start();
}
public void run() {
for (int i = 0; i < 10; i++) {
sd.set((int)(Math.random()*100));
}
}
}
//bersambung...
Contoh Produsen-Konsumen
26
27
28
29
30
31
32
33
34
35
36
37
38
class Consumer implements Runnable {
SharedData sd;
Consumer(SharedData sd) {
this.sd = sd;
new Thread(this, "Consumer").start();
}
public void run() {
for (int i = 0; i < 10 ; i++) {
sd.get();
}
}
}
//bersambung...
Contoh Produsen-Konsumen
39 class
40
41
42
43
44
45
46 }
TestProducerConsumer {
public static void main(String args[])
throws Exception {
SharedData sd = new SharedData();
new Producer(sd);
new Consumer(sd);
}
Contoh Produsen-Konsumen
Contoh hasil:
Generate
Generate
Generate
Generate
Get 65
Generate
Get 23
Generate
Get 49
Generate
8
45
52
65
Get 35
Generate 39
Get 39
Generate 85
Get 85
23
Get 85
Get 85
49
Generate 35
Get 35
35
Get 35
Contoh Produsen-Konsumen
yang telah diperbaiki
1
2
3
4
5
6
7
8
9
10
11
class SharedData {
int data;
boolean valueSet = false;
synchronized void set(int value) {
if (valueSet) {
//hanya dihasilkan jika mempumyai
sebuah nilai
try {
wait();
} catch (InterruptedException ie) {
}
}
//bersambung...
Contoh Produsen-Konsumen
yang telah diperbaiki
System.out.println("Generate " +
value);
13
data = value;
14
valueSet = true;
15
notify();
16
}
17 //bersambung...
12
Contoh Produsen-Konsumen
yang telah diperbaiki
synchronized int get() {
if (!valueSet) {
//producer belum memiliki suatu nilai
try {
wait();
} catch (InterruptedException ie)
18
19
20
21
22
23
{
24
}
}
26 //bersambung...
25
Contoh Produsen-Konsumen
yang telah diperbaiki
System.out.println("Get " + data);
valueSet = false;
notify();
return data;
26
27
28
29
30
}
31 }
32 /*
Bagian kode tertentu tidak berubah. */
Contoh Produsen-Konsumen
Contoh hasil:
Generate
Get 76
Generate
Get 25
Generate
Get 34
Generate
Get 84
Generate
Get 48
Generate
76
25
Get 29
Generate 26
Get 26
Generate 86
34
Get 86
84
Get 65
48
Get 38
29
Get 46
Generate 65
Generate 38
Generate 46
Kemampuan Concurrency
Dirilisi pada Java 2 SE 5.0
Dapat ditemukakn pada paket
java.util.concurrent
Interface
◦ Executor
◦ Callable
Interface Executor
(BEFORE) Mengeksekusi Tugas-tugas
Runnable:
new Thread(<aRunnableObject>).start();
(AFTER) Mengeksekusi Tugas-tugas
Runnable :
<anExecutorObject>.execute(<aRunnableOb
ject>);
Interface Executor
Permasalahan dengan teknik yang lama:
◦ Membuat Thread sangat mahal.
Membutuhkan pengaturan dan penumpukan di
suatu tempat
Dapat mengakibatkan error pada memori
Solusi:
◦ Menggunakan pooling thread
Mengimplementasikan sebuah skema thread pooling
dengan desain yang baik, tidaklah mudah dilakukan
◦ Kesulitan untuk membatalkan atau mematikan
sebuah thread
Interface Executor
Solusi untuk permasalahan dengan teknik yang lama:
◦ Menggunakan interface Executor
Decoupling task submission dari mechanic
mengenai bagaimana setiap tugas dijalankan
Mengggunakan interface Executor :
Executor <executorName> = <anExecutorObject>;
<executorName>.execute(new <RunnableTask1>());
<executorName>.execute(new <RunnableTask2>());
...
Interface Executor
Membuat sebuah object dari tipe Executor:
◦ Tidak dapat di-instantiate
◦ Dapat membuat sebuah class yang
mengimplementasikan interface ini
◦ Dapat menggunakan factory method yang telah
disediakan class Executor
Class Executors juga menyediakan factory method
untuk me-manage thread pool sederhana
Executors Factory Methods
Factory Method dari class Executor
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 method
overloading, juga akan menggunakan object ThreadFactory sebagai argument.
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 object
ThreadFactory sebagai tambahan parameter.
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
object ThreadFactory sebagai tambahan parameter.
public static ExecutorService newSingleThreadExecutor()
Menciptakan sebuah Executor yang digunakan sebagai satu-satu-nya pelaksana dari sebuah antrian thread
yang tidak teratur. Creates an Executor that uses a single worker thread operating off an unbounded
queue. Sebuah overloading method, juga akan menggunakan object ThreadFactory sebagai tambahan
parameter.
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
Interface Executor
Mengontrol eksekusi dan penyelesaian dari
tugas-tugas Runnable
Memberhentikan threads:
executor.shutdown();
Interface Callable
Mengingat kembali:
◦ Dua cara dalam membuat threads:
Menurunkan (Extend) class Thread
Mengimplementasikan (implement) sebuah
interface Runnable
◦ Harus menjalankan method run
public void run() //no throws clause
Interface Callable
◦ interface Runnable tanpa kelemahankelemahannya
Interface Callable
(BEFORE) Mendapatkan hasil dari sebuah tugas Runnable:
public MyRunnable implements Runnable {
private int result = 0;
public void run() {
...
result = someValue;
}
/* hasil attribut terlindung dari perubahan dari
kode lain yang mengakses class ini*/
public int getResult() {
return result;
}
}
Interface Callable
(AFTER) Mendapatkan hasil dari sebuah
tugas Runnable :
import java.util.concurrent.*;
public class MyCallable implements
Callable {
public Integer call() throws
java.io.IOException {
...
return someValue;
}
}
Interface Callable
Method call
V call throws Exception
dimana
V adalah sebuah tipe generic.
Fitur-fitur concurrency yang lain
◦ J2SE 5.0 API documentation
Ringkasan
Threads
◦ Pengertian Thread
◦ State dari Thread
Running
Ready to run
Resumed
Suspended
Blocked
◦ Prioritas
Nilai integer dari angka 1 sampai dengan 10
Context switch
Ringkasan
Class Thread
◦ Constructor
◦ Constants
MAX_PRIORITY
MIN_PRIORITY
NORM_PRIORITY
◦ Methods
currentThread()
getName()
setName(String name)
getPriority()
isAlive()
●
join([long millis,
[int nanos]])
●
sleep(long millis)
●
run()
●
start()
Ringkasan
Membuat Threads
◦ Menurunkan Class Thread
◦ Mengimplementasikan Interface Runnable
◦ Extend vs. Implement
Sinkronisasi
◦ Mengunci sebuah Object
◦ Keyword synchronized
Method header
Object
Ringkasan
Komunikasi Antar Thread (Interthread)
◦ Methods
wait
notify
notifyAll
Kemampuan Concurrency
◦ Interface Executor
Executors factory methods
◦ Interface Callable