Tiang sinyal

Semafor biasanya digunakan saat diperlukan untuk membatasi jumlah utas saat bekerja dengan sistem file. Akses ke file atau sumber daya bersama lainnya dikontrol melalui penghitung. Jika nilainya lebih besar dari nol, akses diperbolehkan, tetapi penghitung akan berkurang.

Pada saat penghitung mengembalikan nol, utas saat ini akan diblokir hingga sumber daya dilepaskan oleh utas lainnya. Jumlah parameter izin harus diatur melalui konstruktor.

Anda harus memilih parameter ini satu per satu, tergantung pada daya komputer atau laptop Anda.

public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + "waiting permission");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + "releases permission");
       semaphore.release();
   }
}

CountDownLatch dan lainnya

CountDownLatch - Memungkinkan beberapa utas menunggu hingga sejumlah operasi yang dilakukan pada utas lainnya selesai. Contohnya adalah penginstalan aplikasi: aplikasi tidak akan dimulai hingga Anda menerima persyaratan penggunaan, hingga Anda memilih folder tempat menginstal program baru, dan seterusnya. Ada metode hitung mundur () khusus untuk ini - metode ini mengurangi penghitung mundur satu per satu.

Segera setelah hitungan menjadi nol, semua utas menunggu di await akan melanjutkan pekerjaannya, dan semua panggilan await berikutnya akan berlalu tanpa menunggu. Penghitung mundur adalah penghitung satu kali dan tidak dapat diatur ulang.

CyclicBarrier - digunakan untuk menyinkronkan sejumlah utas pada satu titik. Penghalang tercapai ketika N utas memanggil metode dan blokir await(...). Setelah itu, penghitung disetel ulang ke nilai aslinya, dan utas yang menunggu akan dilepaskan. Selain itu, jika diperlukan, dimungkinkan untuk menjalankan kode khusus sebelum membuka blokir utas dan mengatur ulang penghitung. Untuk melakukan ini, objek dengan implementasi antarmuka Runnable dilewatkan melalui konstruktor .

Exchanger<V> kelas Exchanger ditujukan untuk pertukaran data antar thread. Itu diketik dan mengetik jenis data yang perlu ditukar oleh utas.

Data dipertukarkan menggunakan satu-satunya metode exchange() dari kelas ini :

V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

Parameter x mewakili buffer data yang akan ditukar. Bentuk kedua dari metode ini juga mendefinisikan parameter timeout , timeout , dan unit , tipe unit waktu yang akan digunakan untuk parameter timeout .

Kelas Phaser memungkinkan Anda menyinkronkan utas yang mewakili satu fase atau tahapan dalam pelaksanaan tindakan keseluruhan. Phaser mendefinisikan objek sinkronisasi yang menunggu hingga fase tertentu selesai. Phaser kemudian melanjutkan ke tahap atau fase berikutnya dan menunggu hingga selesai lagi.

Saat bekerja dengan kelas Phaser , biasanya pertama-tama buat objeknya. Selanjutnya, kita perlu mendaftarkan semua peserta. Untuk mendaftar setiap peserta, metode register() dipanggil , atau Anda dapat melakukannya tanpa metode ini dengan meneruskan jumlah peserta yang diperlukan ke konstruktor Phaser .

Kemudian setiap peserta melakukan serangkaian tindakan tertentu yang membentuk fase tersebut. Dan sinkronisasi Phaser menunggu hingga semua peserta menyelesaikan pelaksanaan fase. Untuk memberi tahu sinkronisasi bahwa fase telah berakhir, peserta harus memanggil metode arrival() atau arrivalAndAwaitAdvance() . Sinkronisasi kemudian beralih ke fase berikutnya.