Home » Java » Java Multithreading (1): Thread dan Kegunaannya

Java Multithreading (1): Thread dan Kegunaannya

by Bagus Dharma Iswara
by Bagus Dharma Iswara

Apa itu MultiThreading ?

Java adalah bahasa pemrograman multi-threaded yang artinya kita dapat mengembangkan program multi-threaded menggunakan Java. Program multi-utas berisi dua atau lebih bagian yang dapat berjalan secara bersamaan dan setiap bagian dapat menangani tugas yang berbeda pada saat yang sama memanfaatkan sumber daya yang tersedia secara optimal khususnya ketika komputer Anda memiliki banyak CPU.

Menurut definisi, multitasking adalah ketika beberapa proses berbagi sumber daya pemrosesan yang umum seperti CPU. Multi-threading memperluas gagasan multitasking menjadi aplikasi di mana Anda dapat membagi operasi tertentu dalam satu aplikasi menjadi utas individu. Setiap utas dapat berjalan secara paralel. OS membagi waktu pemrosesan tidak hanya di antara aplikasi yang berbeda, tetapi juga di antara setiap utas dalam aplikasi. Multi-threading memungkinkan Anda menulis dengan cara di mana banyak aktivitas dapat dilanjutkan secara bersamaan dalam program yang sama.

Multithreading di Java adalah proses menjalankan beberapa utas secara bersamaan. Thread adalah sub-proses ringan, unit pemrosesan terkecil. Multiprocessing dan multithreading, keduanya digunakan untuk mencapai multitasking. Namun, kami menggunakan multithreading daripada multiprocessing karena utas menggunakan area memori bersama. Mereka tidak mengalokasikan area memori terpisah sehingga menghemat memori, dan peralihan konteks antar utas membutuhkan waktu lebih sedikit daripada proses. Java Multithreading banyak digunakan dalam permainan, animasi.

Keutungan MultiThreading pada Java

  1. Multithread tidak memblokir pengguna karena threadnya independen dan Anda dapat melakukan beberapa operasi pada saat yang bersamaan.
  2. Anda dapat melakukan banyak operasi bersama-sama, sehingga dapat menghemat waktu.
  3. Thread bersifat independen, jadi tidak memengaruhi thread lain jika pengecualian terjadi di thread tunggal.

MultiTasking pada java

Multitasking adalah proses menjalankan banyak tugas secara bersamaan. Kami menggunakan multitasking untuk memanfaatkan CPU. Multitasking dapat dicapai dengan dua cara:

  1. Multitasking Berbasis Proses (Multiprocessing).
  2. Multitasking Berbasis Thread (Multithreading).

Multitasking Berbasis Proses (Multiprocessing)

  • Setiap proses memiliki alamat di memori. Dengan kata lain, setiap proses mengalokasikan area memori terpisah.
  • Suatu proses sangatlah berat.
  • Biaya komunikasi antar proses tinggi.
  • Berpindah dari satu proses ke proses lainnya memerlukan waktu untuk menyimpan dan memuat register, peta memori, memperbarui daftar.

Multitasking Berbasis Thread (Multithreading)

  • Thread berbagi ruang alamat yang sama.
  • Thread itu sangat ringan.
  • Biaya komunikasi antar thread rendah.

Apa itu Thread ?

Thread adalah subproses ringan, unit pemrosesan terkecil. Ini adalah jalur eksekusi yang terpisah. Thread sangat independen. Jika terjadi pengecualian di satu Thread, itu tidak memengaruhi Thread lainnya. Ini menggunakan area memori bersama.

Seperti yang ditunjukkan pada gambar di atas, Thread dijalankan di dalam proses. Ada peralihan konteks di antara Thread. Mungkin ada banyak proses di dalam OS, dan satu proses dapat memiliki banyak Thread.

Kelas Thread pada Java

Java menyediakan kelas Thread untuk mencapai pemrograman thread. Kelas thread menyediakan konstruktor dan metode untuk membuat dan melakukan operasi pada thread. Kelas thread memperluas kelas Object dan mengimplementasikan antarmuka Runnable.

Metode Pada Thread Java

  • void start () yaitu Digunakan untuk memulai eksekusi thread.
  • void run () Digunakan untuk melakukan tindakan untuk thread.
  • statis void sleep () Ini thread untuk menggunakan sleep untuk jumlah waktu yang ditentukan.
  • static Thread currentThread () Ini mengembalikan referensi ke objek thread yang sedang dieksekusi.
  • void join () yaitu untuk Menunggu thread mati.
  • int getPriority () Ini mengembalikan prioritas thread.
  • void setPriority () Ini mengubah prioritas thread.
  • String getName () Ini mengembalikan nama thread.
  • void setName () Ini mengubah nama thread.
  • long getId () Ini mengembalikan id thread.
  • boolean isAlive () Ini menguji apakah threadhidup.
  • static void yield () Ini menyebabkan objek thread yang sedang dieksekusi berhenti dan mengizinkan thread lain untuk mengeksekusi sementara.
  • void suspend () Digunakan untuk menangguhkan utas.
  • void resume () Digunakan untuk melanjutkan thread yang ditangguhkan.
  • void stop () Digunakan untuk menghentikan utas.
  • void destroy () Digunakan untuk menghancurkan grup thread dan semua subgrupnya.
  • boolean isDaemon () Ini menguji apakah utas adalah utas daemon.
  • void setDaemon () Ini menandai utas sebagai daemon atau utas pengguna.
  • void interrupt () Ini mengganggu utas.
  • boolean isinterrupted () Ini menguji apakah utas telah terputus.
  • boolean statis terputus () Ini menguji apakah utas saat ini telah terputus.
  • static int activeCount () Ini mengembalikan jumlah utas aktif dalam grup utas saat ini.
  • void checkAccess () Ini menentukan apakah thread yang sedang berjalan memiliki izin untuk mengubah thread.
  • static boolean holdLock () Mengembalikan nilai true jika dan hanya jika thread saat ini memegang kunci monitor pada objek yang ditentukan.
  • static void dumpStack () Digunakan untuk mencetak jejak tumpukan dari utas saat ini ke aliran kesalahan standar.
  • StackTraceElement [] getStackTrace () Ia mengembalikan larik elemen pelacakan tumpukan yang mewakili tumpukan dump dari utas.
  • static int enumerate () Digunakan untuk menyalin setiap grup thread aktif dan subgrupnya ke dalam array yang ditentukan.
  • Thread.State getState () Digunakan untuk mengembalikan status thread.
  • ThreadGroup getThreadGroup () Ini digunakan untuk mengembalikan grup utas tempat utas ini berada
  • String toString () Digunakan untuk mengembalikan representasi string dari thread ini, termasuk nama thread, prioritas, dan grup thread.
  • void notify () Digunakan untuk memberikan notifikasi hanya untuk satu thread yang sedang menunggu objek tertentu.
  • void notifyAll () Ini digunakan untuk memberikan notifikasi ke semua thread yang menunggu dari objek tertentu.
  • void setContextClassLoader () Ini menetapkan konteks ClassLoader untuk Thread.
  • ClassLoader getContextClassLoader () Ini mengembalikan konteks ClassLoader untuk utas.
  • Thread.UncaughtExceptionHandler statis getDefaultUncaughtExceptionHandler () Ia mengembalikan penangan default yang dipanggil saat thread tiba-tiba berhenti karena pengecualian yang tidak tertangkap.
  • static void setDefaultUncaughtExceptionHandler () Ini menetapkan penangan default yang dipanggil ketika sebuah utas tiba-tiba berhenti karena pengecualian yang tidak tertangkap.

Life Cycle sebuah Thread

Sebuah Thread melewati berbagai tahapan dalam siklus hidupnya. Misalnya, thread lahir, dimulai, dijalankan, lalu mati.Bisa berada di salah satu dari lima status. Menurut sun, hanya ada 4 status dalam siklus hidup thread di java baru, dapat dijalankan, tidak dapat dijalankan, dan dihentikan. Tidak ada status berjalan. Tetapi untuk lebih memahami utasnya, kami menjelaskannya di 5 negara bagian.

Siklus hidup utas di java dikendalikan oleh JVM. Status thread java adalah sebagai berikut

  1. New yaitu thread baru memulai siklus hidupnya di status baru. Ini tetap dalam status ini sampai program memulai utas. Itu juga disebut sebagai born thread. berada dalam status baru jika Anda membuat instance kelas Thread tetapi sebelum pemanggilan metode start ().
  2. Runnable yaitu Setelah thread yang baru lahir dimulai, thread menjadi dapat dijalankan. Untaian dalam status ini dianggap sedang menjalankan tugasnya. berada dalam keadaan runnable setelah pemanggilan metode start (), tetapi penjadwal utas belum memilihnya untuk menjadi utas yang berjalan.
  3. Waiting yaitu Terkadang, thread beralih ke status menunggu sementara thread menunggu thread lain melakukan tugas. Sebuah thread bertransisi kembali ke kondisi runnable hanya ketika thread lain memberi sinyal kepada thread yang menunggu untuk melanjutkan eksekusi. dalam status berjalan jika penjadwal utas telah memilihnya.
  4. Timed Waiting yaitu thread yang dapat dijalankan dapat memasuki status menunggu berjangka waktu untuk interval waktu tertentu. Sebuah threaddalam keadaan ini transisi kembali ke keadaan runnable ketika interval waktu itu berakhir atau ketika peristiwa yang menunggu terjadi. Ini adalah keadaan ketika utas masih hidup, tetapi saat ini tidak memenuhi syarat untuk dijalankan.
  5. Terminated (Dead) yaitu Sebuah thread runnable memasuki status terminated ketika menyelesaikan tugasnya atau sebaliknya. Sebuah utas dalam keadaan dihentikan atau mati saat metode run () keluar.

Prioritas Thread

Setiap thread Java memiliki prioritas yang membantu sistem operasi menentukan urutan thread yang dijadwalkan. Prioritas utas Java berada dalam kisaran antara MIN_PRIORITY (konstanta 1) dan MAX_PRIORITY (konstanta 10). Secara default, setiap utas diberi prioritas NORM_PRIORITY (konstanta 5).

Utas dengan prioritas lebih tinggi lebih penting untuk program dan harus dialokasikan waktu prosesor sebelum utas dengan prioritas lebih rendah. Namun, prioritas thread tidak dapat menjamin urutan eksekusi thread dan sangat bergantung pada platform.

Cara Membuat Thread pada Java

Ada dua cara untuk membuat thread yaitu dengan cara berikut

  1. Dengan memperluas kelas Thread.
  2. Dengan mengimplementasikan Runnable Interfaces.

Memperluas Kelas Thread

Kelas thread menyediakan konstruktor dan metode untuk membuat dan melakukan operasi pada thread. Kelas thread memperluas kelas Objek dan mengimplementasikan antarmuka Runnable. Cara pertama membuat thread adalah membuat kelas baru yang memperluas kelas Thread menggunakan dua langkah sederhana berikut. Pendekatan ini memberikan lebih banyak fleksibilitas dalam menangani beberapa thread yang dibuat menggunakan metode yang tersedia di kelas Thread.

Langkah Pertama

Anda perlu mengganti metode run () yang tersedia di kelas Thread. Metode ini menyediakan titik masuk untuk utas dan Anda akan memasukkan logika bisnis lengkap Anda ke dalam metode ini. Berikut ini adalah sintaks sederhana dari metode run () yaitu

public void run( )

Langkah Kedua

Setelah objek Thread dibuat, Anda bisa memulainya dengan memanggil metode start (), yang menjalankan metode panggilan ke run (). Berikut ini adalah sintaks sederhana dari metode start () dapat kita lihat pada kode berikut

void start( );

Berikut adalah program sebelumnya yang ditulis ulang untuk memperpanjang Thread

class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;
   
   ThreadDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      ThreadDemo T1 = new ThreadDemo( "Thread-1");
      T1.start();
      
      ThreadDemo T2 = new ThreadDemo( "Thread-2");
      T2.start();
   }   
}

Maka akan menghasilkan output berikut ini

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Berikut ini adalah kelas lain yang memperluas kelas Thread

// File Name : GuessANumber.java
// Create a thread to extentd Thread

public class GuessANumber extends Thread {
   private int number;
   public GuessANumber(int number) {
      this.number = number;
   }
   
   public void run() {
      int counter = 0;
      int guess = 0;
      do {
         guess = (int) (Math.random() * 100 + 1);
         System.out.println(this.getName() + " guesses " + guess);
         counter++;
      } while(guess != number);
      System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
   }
}

Contoh Lain pada Memperluas Kelas Thread yaitu

class Multi extends Thread{  
public void run(){  
System.out.println("thread is running...");  
}  
public static void main(String args[]){  
Multi t1=new Multi();  
t1.start();  
 }  
}  //output yang dihasilkan yaitu : Output:thread is running...

Kelas Thread Constuctor yang Sering Digunakan

  • Thread()
  • Thread(String name)
  • Thread(Runnable r)
  • Thread(Runnable r,String name)

Mengimplementasikan Runnable Interfaces

Jika kelas Anda dimaksudkan untuk dieksekusi sebagai thread, Anda dapat melakukannya dengan mengimplementasikan Runnable Interfaces. Anda harus mengikuti tiga langkah dasar yaitu

Langkah Pertama

Sebagai langkah pertama, Anda perlu mengimplementasikan metode run () yang disediakan oleh antarmuka Runnable. Metode ini menyediakan titik masuk untuk utas dan Anda akan memasukkan logika bisnis lengkap Anda ke dalam metode ini. Berikut ini adalah sintaks sederhana dari metode run ()

public void run( )

Langkah Kedua

Sebagai langkah kedua, Anda akan membuat instance objek Thread menggunakan konstruktor berikut

Thread(Runnable threadObj, String threadName);

Di mana, threadObj adalah turunan dari kelas yang mengimplementasikan antarmuka Runnable dan threadName adalah nama yang diberikan ke utas baru.

Langkah Ketiga

Setelah objek Thread dibuat, Anda bisa memulainya dengan memanggil metode start (), yang menjalankan metode panggilan ke run (). Berikut ini adalah sintaks sederhana dari metode start ()

void start();

Berikut adalah contoh untuk membuat utas baru dan mulai menjalankannya. Contoh nya adalah pada kode berikut

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;
   
   RunnableDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
      
      RunnableDemo R2 = new RunnableDemo( "Thread-2");
      R2.start();
   }   
}

Maka output yang dihasilkan akan menjadi seperti ini

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Contoh Berikutnya adalah dengan menuliskan kode berikut Program ThreadClassDemo berikut mendemonstrasikan beberapa metode kelas Thread ini. Pertimbangkan kelas DisplayMessage yang mengimplementasikan Runnable

// File Name : DisplayMessage.java
// Create a thread to implement Runnable

public class DisplayMessage implements Runnable {
   private String message;
   
   public DisplayMessage(String message) {
      this.message = message;
   }
   
   public void run() {
      while(true) {
         System.out.println(message);
      }
   }
}

Kemudian kita dapat membuat contoh kode lainnya seperti dibawah ini

class Multi3 implements Runnable{  
public void run(){  
System.out.println("thread is running...");  
}  
  
public static void main(String args[]){  
Multi3 m1=new Multi3();  
Thread t1 =new Thread(m1);  
t1.start();  
 }  
}  // maka akan menghasilkan output : Output:thread is running...

Selanjutnya adalah kita buat sebuah gabungan dari 2 metode diatas yaitu

// File Name : ThreadClassDemo.java
public class ThreadClassDemo {

   public static void main(String [] args) {
      Runnable hello = new DisplayMessage("Hello");
      Thread thread1 = new Thread(hello);
      thread1.setDaemon(true);
      thread1.setName("hello");
      System.out.println("Starting hello thread...");
      thread1.start();
      
      Runnable bye = new DisplayMessage("Goodbye");
      Thread thread2 = new Thread(bye);
      thread2.setPriority(Thread.MIN_PRIORITY);
      thread2.setDaemon(true);
      System.out.println("Starting goodbye thread...");
      thread2.start();

      System.out.println("Starting thread3...");
      Thread thread3 = new GuessANumber(27);
      thread3.start();
      try {
         thread3.join();
      } catch (InterruptedException e) {
         System.out.println("Thread interrupted.");
      }
      System.out.println("Starting thread4...");
      Thread thread4 = new GuessANumber(75);
      
      thread4.start();
      System.out.println("main() is ending...");
   }
}

Ini akan menghasilkan hasil sebagai berikut. Anda dapat mencoba contoh ini lagi dan lagi dan Anda akan mendapatkan hasil yang berbeda setiap saat

Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......

Jika Anda tidak memperluas kelas Thread, objek kelas Anda tidak akan diperlakukan sebagai objek thread. Jadi, Anda perlu membuat objek kelas Thread secara eksplisit. Kami meneruskan objek kelas Anda yang mengimplementasikan Runnable sehingga metode run () kelas Anda dapat mengeksekusi.

You may also like