Java SynchronousQueue: ส่งต่อแบบไม่มีชั้นวางพัก
ชื่อมีคำว่า Queue แต่ SynchronousQueue ไม่มีความจุเก็บ item เลย put จะสำเร็จเมื่อมี take มารับคู่กัน เหมาะกับ direct handoff ที่ต้องการ backpressure ทันทีครับ
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
SynchronousQueue<String> handoff = new SynchronousQueue<>(true);
ExecutorService pool = Executors.newSingleThreadExecutor();
try {
Future<Boolean> sent = pool.submit(
() -> handoff.offer("report", 1, TimeUnit.SECONDS));
String received = handoff.poll(1, TimeUnit.SECONDS);
assert "report".equals(received);
assert sent.get();
assert handoff.isEmpty();
assert handoff.remainingCapacity() == 0;
} finally {
pool.shutdownNow();
}
}
}
นึกถึงช่องส่งอาหารที่ไม่มีโต๊ะพัก คนครัวต้องเจอพนักงานเสิร์ฟตรงช่องพอดี ระบบจึงไม่สะสมงานเงียบ ๆ แต่ throughput จะผูกกับฝั่งที่ช้ากว่า Constructor ที่รับ true เลือก fairness แบบเข้าคิว ซึ่งคาดเดาลำดับง่ายขึ้นแต่มีค่า overhead เทียบกับค่าเริ่มต้น
ใช้ offer/poll พร้อม timeout เมื่อ thread ห้ามค้างตลอด และอย่าดู size() เพื่อคาดว่ามีงานรอ เพราะมันเป็นศูนย์เสมอ หากธุรกิจต้องทน burst ให้ใช้ queue ที่มี capacity ชัดและ metric วัด backlog แทน
Recap
- ไม่มี storage ภายใน ทุก item ต้องจับคู่ producer-consumer
- ใช้ timeout และ cancellation policy
- เลือก fairness เมื่อ ordering สำคัญจริง
- ใช้ bounded queue หากต้องดูดซับ burst