我需要收集一些有关用户管理的 Telegram 频道的统计信息。要使用 Telegram API,我使用tdlight-java。此库中对 Telegram 的每个请求都通过 SimpleTelegramClient 对象执行。该对象在自己的线程上运行并异步处理请求。因此,以下方法将返回 0,因为对客户端方法的调用尚未完全完成,但 getUserID 方法已经返回了一个值:
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 线程将被阻塞,内部请求永远无法完成,从而导致死锁。
你能给我一个更好的同步想法吗?