ユーザーが管理する Telegram チャネルに関する統計を収集する必要があります。Telegram API を操作するには、 tdlight-javaを使用します。このライブラリ内の Telegram への各リクエストは、SimpleTelegramClient オブジェクトを通じて実行されます。そのオブジェクトは独自のスレッドで実行され、リクエストを非同期的に処理します。したがって、クライアント メソッドへの呼び出しは完全には完了していませんが、getUserID メソッドはすでに値を返しているため、次のメソッドは 0 を返します。
public long getUserId() {
AtomicLong userID = new AtomicLong();
client.send(new TdApi.GetMe(), (me) -> {
userID.set(me.get().id);
});
return userID.get();
}
クライアントのメソッドが完了した後にのみ、メソッドの実行を継続する必要があります。そこで、同期ブロックとロックを使用することにしました。
public long getUserId() throws InterruptedException{
final Object lock = new Object();
AtomicLong userID = new AtomicLong();
synchronized (lock){
client.send(new TdApi.GetMe(), (me) -> {
synchronized (lock) {
userID.set(me.get().id);
lock.notify();
}
});
lock.wait();
}
return userID.get();
}
しかし、それは最善の解決策のようには見えません。さらに、このアプローチでは、内部 API 呼び出しを使用する際にいくつかの制限が生じます。
synchronized (lock){
client.send(new TdApi.GetMe(), (me) -> {
synchronized (anotherLock) {
client.send(new TdApi.GetMe(), (me) -> {
synchronized(anotherLock){
anotherLock.notify();
}
});
anotherLock.wait();
}
synchronized(lock){
lock.notify();
}
});
lock.wait();
}
この場合、TelegramClient スレッドはブロックされ、内部要求は完了せず、デッドロックが発生します。
同期のより良いアイデアを教えてください。