สัญญาณ
![](https://cdn.codegym.cc/images/article/5b56b330-d15d-450e-9d26-15f951f2a98a/1024.jpeg)
สัญญาณมักใช้เมื่อจำเป็นต้องจำกัดจำนวนเธรดเมื่อทำงานกับระบบไฟล์ การเข้าถึงไฟล์หรือทรัพยากรที่ใช้ร่วมกันอื่นๆ ถูกควบคุมผ่านตัวนับ หากค่ามากกว่าศูนย์อนุญาตให้เข้าถึงได้ แต่ตัวนับจะลดลงในเวลาเดียวกัน
ในขณะที่ตัวนับส่งคืนค่าศูนย์ เธรดปัจจุบันจะถูกบล็อกจนกว่าเธรดอื่นจะปล่อยทรัพยากร จำนวนพารามิเตอร์สิทธิ์ต้องตั้งค่าผ่านตัวสร้าง
คุณต้องเลือกพารามิเตอร์นี้ทีละรายการ ขึ้นอยู่กับพลังของคอมพิวเตอร์หรือแล็ปท็อปของคุณ
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 และอื่นๆ
CountDownLatch - อนุญาตให้หลายเธรดรอจนกว่าจำนวนการดำเนินการที่ดำเนินการกับเธรดอื่นจะเสร็จสมบูรณ์ ตัวอย่างคือการติดตั้งแอปพลิเคชัน: จะไม่เริ่มจนกว่าคุณจะยอมรับเงื่อนไขการใช้งาน จนกว่าคุณจะเลือกโฟลเดอร์ที่จะติดตั้งโปรแกรมใหม่ เป็นต้น มีวิธีพิเศษ สำหรับ การนับถอยหลัง () สำหรับวิธีนี้ - วิธีนี้จะลดจำนวนนับถอยหลังทีละหนึ่ง
ทันทีที่การนับถึงศูนย์ เธรดการรอทั้งหมดในการรอจะทำงานต่อไป และการเรียกการรอที่ตามมาทั้งหมดจะผ่านไปโดยไม่ต้องรอ ตัวนับถอยหลังเป็นตัวนับแบบครั้งเดียวและไม่สามารถรีเซ็ตได้
CyclicBarrier - ใช้เพื่อซิงโครไนซ์จำนวนเธรดที่กำหนด ณ จุดหนึ่ง ถึงสิ่งกีดขวางเมื่อเธรด N เรียกใช้เมธอด wait(...) และบล็อก หลังจากนั้น ตัวนับจะถูกรีเซ็ตเป็นค่าเดิม และเธรดที่รอจะถูกปล่อย นอกจากนี้ หากจำเป็น คุณสามารถรันโค้ดแบบกำหนดเองก่อนที่จะเลิกบล็อกเธรดและรีเซ็ตตัวนับ ในการทำเช่นนี้ วัตถุที่มีการใช้งาน อินเทอร์เฟซ ที่เรียกใช้ได้ จะถูกส่งผ่านตัว สร้าง
Exchanger<V> — คลาส Exchangerมีไว้สำหรับการแลกเปลี่ยนข้อมูลระหว่างเธรด มันถูกพิมพ์และพิมพ์ประเภทของข้อมูลที่เธรดต้องการแลกเปลี่ยน
ข้อมูลถูกแลกเปลี่ยนโดยใช้เมธอด exchange()เดียว ของคลาสนี้ :
V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
พารามิเตอร์ x แสดงถึงบัฟเฟอร์ข้อมูลที่จะแลกเปลี่ยน รูปแบบที่สองของเมธอดยังกำหนด พารามิเตอร์ การหมดเวลาการหมดเวลา และหน่วยประเภทของหน่วยเวลาที่จะใช้สำหรับ พารามิเตอร์ การหมดเวลา
คลาสPhaserช่วยให้คุณสามารถซิงโครไนซ์เธรดที่แสดงถึงเฟสหรือสเตจเดียวในการดำเนินการของการดำเนินการโดยรวม Phaserกำหนดอ็อบเจกต์การซิงโครไนซ์ที่รอจนกว่าเฟสหนึ่งจะเสร็จสิ้น จากนั้นPhaserจะไปยังสเตจหรือเฟสถัดไปและรอให้เสร็จสิ้นอีกครั้ง
เมื่อทำงานกับ คลาส Phaserเป็นเรื่องปกติที่จะสร้างวัตถุก่อน ต่อไปเราต้องลงทะเบียนผู้เข้าร่วมทั้งหมด ในการลงทะเบียนสำหรับผู้เข้าร่วมแต่ละคน เมธอด register() เรียกว่า หรือคุณสามารถทำได้โดยไม่ต้องใช้วิธีนี้โดยส่งจำนวนผู้เข้าร่วมที่ต้องการไปยังตัว สร้าง Phaser
จากนั้นผู้เข้าร่วมแต่ละคนดำเนินการชุดของการกระทำที่ประกอบขึ้นเป็นขั้นตอน และ เครื่องซิงโครไนซ์ Phaserจะรอจนกว่าผู้เข้าร่วมทั้งหมดจะเสร็จสิ้นการดำเนินการของเฟส ในการแจ้งซิงโครไนเซอร์ว่าเฟสสิ้นสุดแล้ว ผู้เข้าร่วมจะต้องเรียกเมธอด arrival ( )หรือarrivalAndAwaitAdvance() จากนั้นซิงโครไนเซอร์จะไปยังเฟสถัดไป