تحتوي هذه المكتبة على واجهتين برمجيتين، Java وKotlin، ضمن JVM واحدة. TicketBroker هي واجهة برمجية قائمة على كوروتين Kotlin، بينما BlockingTicketBroker واجهة حاجبة صديقة لـ Java يمكن استخدامها دون كوروتين (مبنية على java.time.Duration). كلتاهما تغلّفان داخليًا نفس الوسيط (broker).
val broker = TicketBroker.connect("127.0.0.1:5225")
broker.waitReady(5.seconds)
val ticket = broker.acquire("key", 5.seconds, 30.seconds)
ticket.release()
broker.close()مثال على التزامن (إقصاء متبادل للإيداع/السحب عبر قفل خاص بكل حساب):
suspend fun transaction(broker: TicketBroker, account: Int, delta: Long) {
val key = "account-$account"
val ticket = try {
broker.acquire(key, wait, lease)
} catch (e: Exception) {
log.error("account {} acquire failed: {}", account, e.message)
return
}
try {
val before = balances[account]
yield()
balances[account] = before + delta
} finally {
ticket.close() // إرجاع تلقائي في الخلفية
}
val (action, sign) = if (delta < 0) "withdraw" to '-' else "deposit" to '+'
log.info("account $account $action $sign\$$AMOUNT -> \$${balances[account]}")
}try (BlockingTicketBroker broker = BlockingTicketBroker.connect(List.of("127.0.0.1:5225"))) {
broker.waitReady(Duration.ofSeconds(5));
BlockingTicket ticket = broker.acquire("key", Duration.ofSeconds(5), Duration.ofSeconds(30));
ticket.release();
System.out.println("pass");
}مثال على التزامن (قفل خاص بكل حساب، ينفَّذ في وقت واحد عبر عدة خيوط باستخدام ExecutorService):
void transaction(BlockingTicketBroker broker, int account, long delta) {
String key = "account-" + account;
try (BlockingTicket ticket = broker.acquire(key, WAIT, LEASE)) {
long before = balances[account];
Thread.yield();
balances[account] = before + delta;
}
String action = delta < 0 ? "withdraw" : "deposit";
char sign = delta < 0 ? '-' : '+';
log.info("account {} {} {}${} -> ${}", account, action, sign, AMOUNT, balances[account]);
}راجع الأمثلة الكاملة في ExampleSimpleTest.kt / ExampleBankTest.kt (Kotlin), ExampleSimpleJavaTest.java / ExampleBankJavaTest.java (Java).