0

我需要收集一些有关用户管理的 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 线程将被阻塞,内部请求永远无法完成,从而导致死锁。

你能给我一个更好的同步想法吗?

4

0 回答 0