Download JENI Slides-Intro2-Bab09

Document related concepts
no text concepts found
Transcript
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
Related documents