Semaphore dalam Java ialah bantuan penyegerakan yang mengehadkan bilangan utas yang boleh mengakses sumber yang dikongsi pada bila-bila masa. Ia adalah sebahagian daripada pakej java.util.concurrent dan digunakan untuk mengurus akses serentak kepada sumber, seperti fail, pangkalan data atau sambungan rangkaian.
Semafor mengawal akses kepada beberapa set permit. Setiap permit mewakili hak untuk mengakses sumber tertentu. Semaphore menjejaki bilangan permit yang tersedia, yang menentukan bilangan utas yang boleh mengakses sumber secara serentak.
Permit : Token atau tiket yang membenarkan urutan meneruskan mengakses sumber kongsi.
Apabila anda mencipta semafor, anda menyatakan bilangan permit yang tersedia. Nombor ini mentakrifkan bilangan utas yang boleh mengakses sumber secara serentak.
Sebelum benang boleh mengakses sumber, ia mesti memperoleh permit daripada semaphore. Ini dilakukan menggunakan kaedah acquire().
Peroleh : Kaedah ini dipanggil apabila benang ingin mengakses sumber. Jika permit tersedia, semaphore mengurangkan bilangan permit yang tersedia dan membenarkan utas untuk diteruskan. Jika tiada permit tersedia, utas akan disekat sehingga permit tersedia.
Kelakuan Menyekat : Jika tiada permit tersedia, urutan yang memanggil acquire() akan disekat (iaitu, ia akan menunggu) sehingga urutan lain mengeluarkan permit.
Setelah benang selesai menggunakan sumber, ia harus mengeluarkan permit untuk menyediakannya untuk urutan lain. Ini dilakukan menggunakan kaedah release().
Keluaran : Kaedah ini menambah bilangan permit yang ada. Jika terdapat sebarang utas menunggu permit, salah satu daripadanya akan dinyahsekat dan dibenarkan untuk memperoleh permit.
Terdapat dua jenis semaphore di Jawa:
Untuk lebih memahami cara semafor berfungsi, mari lihat pelaksanaan praktikal. Kami akan mencipta senario mudah di mana beberapa utas cuba mengakses sumber terhad.
import java.util.concurrent.Semaphore; public class SemaphoreDemo { // Creating a semaphore with 3 permits private static final Semaphore semaphore = new Semaphore(3); public static void main(String[] args) { // Creating and starting 6 threads for (int i = 1; i <= 6; i++) { new WorkerThread("Worker " + i).start(); } } static class WorkerThread extends Thread { private String name; WorkerThread(String name) { this.name = name; } @Override public void run() { try { System.out.println(name + " is trying to acquire a permit..."); // Acquiring the semaphore semaphore.acquire(); System.out.println(name + " acquired a permit."); // Simulating work by sleeping Thread.sleep(2000); System.out.println(name + " is releasing a permit."); } catch (InterruptedException e) { e.printStackTrace(); } finally { // Releasing the semaphore semaphore.release(); } } } }
Dalam contoh ini, kami mencipta semaphore dengan tiga permit, bermakna hanya tiga utas boleh mengakses bahagian kritikal kod pada bila-bila masa. Kami kemudian mencipta enam utas, yang kesemuanya cuba mendapatkan permit. Setelah benang memperoleh permit, ia mensimulasikan beberapa kerja dengan tidur selama dua saat sebelum melepaskan permit.
Apabila anda menjalankan kod di atas, output akan kelihatan seperti ini:
Worker 1 is trying to acquire a permit... Worker 1 acquired a permit. Worker 2 is trying to acquire a permit... Worker 2 acquired a permit. Worker 3 is trying to acquire a permit... Worker 3 acquired a permit. Worker 4 is trying to acquire a permit... Worker 5 is trying to acquire a permit... Worker 6 is trying to acquire a permit... Worker 1 is releasing a permit. Worker 4 acquired a permit. Worker 2 is releasing a permit. Worker 5 acquired a permit. Worker 3 is releasing a permit. Worker 6 acquired a permit.
Di sini, tiga utas pertama berjaya memperoleh permit dan memulakan tugas mereka. Benang yang tinggal mesti menunggu sehingga permit dikeluarkan sebelum ia boleh meneruskan.
Semaphore amat berguna dalam senario di mana anda perlu mengehadkan bilangan akses serentak kepada sumber tertentu, seperti:
Walaupun semaphore adalah alat yang berkuasa, ia datang dengan set kelebihan dan kekurangan mereka sendiri.
Fleksibiliti : Semaphore membolehkan kawalan tepat ke atas akses sumber oleh berbilang rangkaian.
Skalabiliti : Semaphore boleh mengurus akses kepada sejumlah besar sumber dengan mudah.
Kesaksamaan : Semaphore boleh dikonfigurasikan untuk memastikan rangkaian memperoleh permit dengan cara yang adil.
Kerumitan : Menggunakan semafor boleh memperkenalkan kerumitan ke dalam kod anda, menjadikannya lebih sukar untuk nyahpepijat.
Kebuntuan : Jika tidak dikendalikan dengan betul, semafor boleh menyebabkan kebuntuan di mana benang disekat selama-lamanya menunggu permit.
Untuk mengelakkan perangkap biasa dan memanfaatkan semaphore sepenuhnya, pertimbangkan amalan terbaik berikut:
Daripada menggunakan acquire(), yang menyekat selama-lamanya, anda boleh menggunakan tryAcquire() untuk cuba memperoleh permit dengan tamat masa. Ini menghalang urutan daripada tersekat menunggu.
import java.util.concurrent.Semaphore; public class SemaphoreDemo { // Creating a semaphore with 3 permits private static final Semaphore semaphore = new Semaphore(3); public static void main(String[] args) { // Creating and starting 6 threads for (int i = 1; i <= 6; i++) { new WorkerThread("Worker " + i).start(); } } static class WorkerThread extends Thread { private String name; WorkerThread(String name) { this.name = name; } @Override public void run() { try { System.out.println(name + " is trying to acquire a permit..."); // Acquiring the semaphore semaphore.acquire(); System.out.println(name + " acquired a permit."); // Simulating work by sleeping Thread.sleep(2000); System.out.println(name + " is releasing a permit."); } catch (InterruptedException e) { e.printStackTrace(); } finally { // Releasing the semaphore semaphore.release(); } } } }
Untuk mengelakkan kebocoran sumber, sentiasa keluarkan permit dalam blok akhirnya. Ini memastikan permit dikeluarkan walaupun pengecualian berlaku.
Jika anda hanya perlu mengunci dan membuka kunci sumber untuk satu utas, pertimbangkan untuk menggunakan ReentrantLock atau disegerakkan dan bukannya semafor binari.
Semaphore ialah alat yang berkuasa untuk mengurus konkurensi dalam Java, membolehkan anda mengawal bilangan utas yang mengakses sumber yang dikongsi. Dengan mengikuti teknik dan amalan terbaik yang digariskan dalam artikel ini, anda boleh melaksanakan semafor dengan berkesan dalam aplikasi Java anda untuk memastikan pengurusan sumber yang selamat dan cekap.
Jika anda mempunyai sebarang soalan atau ingin berkongsi pengalaman anda sendiri dengan semaphore, sila komen di bawah!
Baca siaran lebih lanjut di : Teknik Mengurus Concurrency dalam Java Menggunakan Semaphore
Atas ialah kandungan terperinci Teknik Mengurus Concurrency dalam Java Menggunakan Semaphore. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!