2

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

0 Answers0