I need to gather some statistics about Telegram channels administrated by user. To work with the Telegram API I use tdlight-java. Each request to Telegram in this library performes through the SimpleTelegramClient object. That object runs on its own thread and processes requests asynchronously. So, the following method will return 0 because the call to the client method is not fully completed, but the getUserID method is already returning a value:
public long getUserId() {
AtomicLong userID = new AtomicLong();
client.send(new TdApi.GetMe(), (me) -> {
userID.set(me.get().id);
});
return userID.get();
}
I need my methods to continue executing only after the client's methods complete. So, I decided to use synchronized blocks and locks:
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();
}
But it doesn's looks like a best solution. In addition, this approach produces some restrictions while using inner API calls:
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();
}
In this case, the TelegramClient thread will be blocked and the inner request will never be completed, resulting in a deadlock.
Can you provide me with a better idea of synchronization, please