Concurrent Programming
Apa Itu Concurret Programming?
Concurrent Programming merupakan sebuah konsep di dalam pemrograman yang memungkinkan suatu komputasi berjalan tanpa hatus menunggu komputasi lainnya diselesaikan terlebih dahulu.
Java merupakan salah satu Bahasa yang bersifat multi-threaded sehingga mendukung untuk konsep concurrency.
Apa itu Proses dan Thread?
Java Virtual Machine bertugas untuk menjalalankan proses/process. JVM hanya menjalankan satu proses dalam satu waktu. Satu buah proses identik dengan satu buah unit yang mempunyai ruang memori tersenditri(heap). Apabila ada dua buah proses berjalan di Java secara bersamaan maka masing-masing dari merekan akan memiliki ruang memori sendiri dan tidak bisa saling berbagi.
Satu buah proses biasanya terbagi menjdai setidaknya satu buah Thread atau lebih. Thread adalah satu buah unit yang ada dalam satu proses. Berbeda dengan proses yang tidak bisa berbagi sunber daya memori dengan proses lainnya, thread bisa berbagi sumber daya memori antar thread. Setiap thread akan mempunyai stack-nya sendiri.
Dikarenakan thread bisa berbagi sumber daya memori maka kita bisa menjalankna beberapa thread stack uang berbeda dalam satu prosesnya secara bergantian dan asalkan masu dalam satu heap. Konsep itu disebut sebagai multithreading.
Siklus Hidup Thread
Thread memiliki lima siklus hidup. Masing-masing siklus hidup bisa terjadi akibat terpicu jalannya suatu method pada thread atau bisa berjalan apabila ada suatu keadaan yang terpenuhi.
Berikut penjelasan siklus diatas :
- New = Kondisi dimana thread baru saja dideklarasikan dan memulai siklus hidupnya dalam kondisi awal.
- Runnable = Kondisi dimana thread dalam stage new siap dijalankan.
- Waiting = Kondisi dimana thread sedang menunggu giliran untuk dijalakan.
- Running = Kondisi dimana thread sedang dijalankan. Setelah melewati fase ini maka sebuauh thread bisa saja masuk ke dalam fase Dead atau bisa masuk ke fase waiting apabila masih akan dijalankan kembali (menunggu giliran berikutnya).
- Dead = Kondisi di mana thread sudah dijalankan dan tidak lagi dijalankan.
Priority Sebuah Thread
Bersadarkan penjelasan sbelumnya maka sebuah thread bisa dijalankan bergantian dengan thread dari stack thread lainnya.
Pada proses menjalankannya, urutan berjalannya sebuah thread ditentukan berdasarkan prioritas thread tersebut.
Ada tiga jenis prioritas yang bisa diberikan pada sebuah thread :
- MAX_PRIORITY = Prioritas ini akan memberikan prioritas tinggi untuk dijadwalkan kepada sebuah thread. Nilai dari prioritas ini adalah konstansta bernilai 10.
- NORM_PRIORITY = Secara default, sebuah thread akan memiliki prioritas ini. Nilai dari prioritas ini adalah konstanta bernilai 5.
- MIN_PRIORITY = Prioritas ini akan meberikan prioritas rendah untuk dijadwalkan kepada sebuah thread. Nilai dari prioritas ini adalah konstanta benilai 1.
Sebuah thread yang memiliki prioritas lebih tinggi akan cenderung lebih penting daripada thread dari thread stack lainnya dan akan cenderung lebih dialokasikan untuk dijalankan, tetapi tidak serta merta itu merupakan urutan baku dalam menjalankan sebuah thread ada beberapa faktor lainnya.
Cara Penggunaan Multithreading
Ada dua cara dalam pengimplementasikan konsep concurrency pada Java yaitu :
- Mengimplementasikan Interface “Runnable”.
- Mengimplementasikan dengan meng-extend kelas “Thread”.
Implementasi Multithreading dengan Interface Runnable
Pada cara pertama, kitaa akan membuat kelas yang mengimplementasikan Interface “Runnable”.
Format Interface “Runnable” sebagai berikut:
public interface Runnable{
public abstract void run();
}
Mari kita implementasikan dengan membuat kelas “ThreadSaya”
Kelas ThreadSaya.java :
public class ThreadSaya implements Runnable {
private Thread thread;
private String namaThread;
public ThreadSaya(String namaThread){
this.namaThread = namaThread;
System.out.println("Thread" + namaThread + "diciptakan");
}
@Override
public void run() {
System.out.println("Thread" + namaThread + "dijalankan");
try {
for (int i = 10; i > 0; i--){
System.out.println("Thread" + namaThread + "Ke-" + i);
thread.sleep(50);
}
} catch (InterruptedException e){
System.out.println("Thread" + namaThread + "diinterupsi");
}
System.out.println("Thread" + namaThread + "selesai");
}
public void start(){
System.out.println("Thread" + namaThread + "dimulai");
if (thread == null){
thread = new Thread(this, namaThread);
thread.start();
}
}
}
dan Kemudian membuat kelas TesterRunnable.java :
public class TesterRunnable {
public static void main(String[] args) {
ThreadSaya thread1 = new ThreadSaya("Satu");
ThreadSaya thread2 = new ThreadSaya("Dua");
thread1.start();
thread2.start();
}
}
Dapat dilihat bahwa eksekusi antara thread satu dengan thread dua dilakukan secara bergantian dan eksekusi thread dua tidak harus menunggu eksekusi thread satu selesai lebih dahulu.
Implementasi Multithreading dengan Kelas Thread
Selain menggunakan Interface “Runnable”, kita juga bisa menggunakan cara yang kedua yaitu meng-extend kelas Thread untuk mengimplementasikan multithreading.
Mari kita implementasikan dengan kasus yang sama dengan meng-extend kelas “Thread”.
Mari kita buat kelas ThreadSaya.java :
public class ThreadSaya extends Thread {
private Thread thread;
private String namaThread;
public ThreadSaya(String namaThread){
this.namaThread = namaThread;
System.out.println("Thread" + namaThread + "diciptakan");
}
@Override
public void run() {
System.out.println("Thread" + namaThread + "dijalankan");
try {
for (int i = 10; i > 0; i--){
System.out.println("Thread" + namaThread + "Ke-" + i);
thread.sleep(50);
}
} catch (InterruptedException e){
System.out.println("Thread" + namaThread + "diinterupsi");
}
System.out.println("Thread" + namaThread + "selesai");
}
public void start( int priority){
System.out.println("Thread" + namaThread + "dimulai");
if (thread == null){
thread = new Thread(this, namaThread);
thread.setPriority(priority);
thread.start();
}
}
}
Membuat kelas TesterThread.java :
public class TesterThread {
public static void main(String[] args) {
ThreadSaya thread1 = new ThreadSaya("Satu");
ThreadSaya thread2 = new ThreadSaya("Dua");
thread1.start();
thread2.start();
thread1.start(Thread.MAX_PRIORITY);
thread2.start(Thread.NORM_PRIORITY);
}
}
Sekali lagi, prioritas thread tidak menjamin bahwa thread dari thread stack tersebut selalu dieksekusi lebih (baik lebih cepat maupun lebih banyak) dibanding thread dengan prioritas yang lebih rendah. Ada beberapa parameter diluar prioritas thread yang mempengaruhi urutan berjalannya sebuah thread.
Operasi-Operasi Umum Concurrency di Java
Untuk bisa lebih mengoptimalkan konsep concurrency di Java, ada beberapa operasi thread lain yang bisa digunakan.
- void suspend() = Method ini akan membuat thread ke dalam kondisi suspended dan thhread akan dilanjutkan apabila ada pemanggilan method resume().
- void stop() = Method ini akan menghentikan pemrosesan thread dan mengubahnya ke dalam state dead.
- void resume() = Methode ini akan melanjutkan pemrosesan thread yang si-suspend.
- void wait() = Method ini akan membuat thread yang sedang dijalankan (belum selesai diproses unuk thread tersebut) memasuki kondisi wair\t dan thread akan dilanjutkan apabila method notify() dipanggil.
- void notify() = Method ini akan melanjutkan satu thread yang dalam kondisi wait.
Mari kita implementasikan dengan membuat beberapa kelas :
Membuat kelas ThreadMethod.java :
public class ThreadMethode implements Runnable {
public Thread thread;
private String namaThread;
private boolean suspended = false;
public ThreadMethode(String namaThread){
this.namaThread = namaThread;
System.out.println("Thread" + namaThread + "diciptakan");
}
@Override
public void run() {
System.out.println("Thread" + namaThread + "dijalankan");
try{
for (int i = 10; i > 0; i--){
System.out.println("Thread" + namaThread + "Ke- " + i);
Thread.sleep(300);
}
synchronized (this){
while (suspended){
wait();
}
}
} catch (InterruptedException e) {
System.out.println("Thread" + namaThread + "dinterupsi");
}
System.out.println("Thread" + namaThread + "selesai");
}
public void start(){
System.out.println("Thread" + namaThread + "dimulai");
if (thread == null){
thread = new Thread(this, namaThread);
thread.start();
}
}
public void suspend(){
suspended = true;
}
synchronized void resume(){
suspended = false;
notify();
}
}
Membuat kelas TeseterThread.java :
public class TesterThread {
public static void main(String[] args) {
ThreadMethode thread1 = new ThreadMethode("Satu");
ThreadMethode thread2 = new ThreadMethode("Dua");
thread1.start();
thread2.start();
try{
Thread.sleep(1000);
thread1.suspend();
System.out.println("Thread Satu di-suspend");
Thread.sleep(1000);
thread1.resume();
System.out.println("Thread Satu dilanjutkan");
thread2.suspend();
System.out.println("Thread Dua di-suspend");
Thread.sleep(1000);
thread2.resume();
System.out.println("Thread Dua dilanjutkan");
} catch (InterruptedException e){
System.out.println("Thread utama siinterupsi");
}
try{
System.out.println("Menunggu thread selesai dijalankan");
thread1.thread.join();
thread2.thread.join();
}catch (InterruptedException e ) {
System.out.println("Thread utama siinterupsi");
}
System.out.println("Main thread selesai");
}
}
Semoga bermanfaat dan bisa kita bagi keteman yang lainnya. Sampai jumpa lagi.