• ZOU志伟
    2019-04-03
    不合理,会导致很多请求超时,看了源码是调用signalAll()

    作者回复: 写这一章的时候还是signal,后来有人提了个bug,就改成signalall了

     3
     59
  • 张天屹
    2019-04-04
    我理解异步的本质是利用多线程提升性能,异步一定是基于一个新开的线程,从调用线程来看是异步的,但是从新开的那个线程来看,正是同步(等待)的,只是对于调用方而言这种同步是透明的。正所谓生活哪有什么岁月静好,只是有人替你负重前行。

    作者回复: 总结的太有文采了!异步加上非阻塞IO才有威力

     6
     45
  • 天涯煮酒
    2019-04-02
    合理。

    每个rpc请求都会占用一个线程并产生一个新的DefaultFuture实例,它们的lock&condition是不同的,并没有竞争关系

    这里的lock&condition是用来做异步转同步的,使get()方法不必等待timeout那么久,用得很巧妙
     1
     27
  • 10buns
    2019-04-04
    signal唤醒任意一个线程竞争锁,signalAll唤醒同一个条件变量的所有线程竞争锁。但都只有一个线程获得锁执行。区别只是被唤醒线程的数量。
    所以用signalall可以避免极端情况线程只能等待超时,看了代码也是替代了signal
    
     15
  • 密码123456
    2019-04-02
    不一定。如果这个类是单例,那就不合理。如果是一个实例对应一个请求,那就合理。
    
     13
  • 右耳听海
    2019-04-28
    in the method of org.apache.dubbo.remoting.exchange.support.DefaultFuture#doReceived, I think we should call done.signalAll() instead of done.signal() ,and it's unnecessary to check done != null because it's always true

    作者回复: 留言这两点有同学都提到了。我表示震撼!

    
     7
  • 约书亚
    2019-04-06
    我有点不理解为什么这么多说合理的同学,Future这种类不应该经常由于用在闭包中,导致在多线程多上下文中传递嘛?如果我有多个线程都对同一个DefaultFuture实例调用get,而每个被唤醒的线程又不signal其他线程,那不就是只有一个线程最终会被唤醒,其他调用get的线程都是因为超时获取到的结果嘛?
    
     7
  • Geek_e6f3ec
    2019-05-15
    老师关于dubbo源码的执行流程有一点疑问。
    以下是源码
    // 调用通过该方法等待结果
    Object get(int timeout){
            long start = System.nanoTime();
            lock.lock();
            try{
                while (!isDone()){
                    done.wait(timeout); // 在这里调用了等待方法后面的代码还能执行吗? 我理解的管程,是在条件变量等待队列中阻塞等待,被唤醒之后也不是马上执行也要去管程入口等待队列,也就是lock.lock处等待获取锁。 老师是这样的吗?
                    long cur = System.nanoTime();
                    if (isDone()||cur-start> timeout){
                        break;
                    }
                }
            }finally {
                lock.unlock();
            }
            return returnFromResponse();

        }

     



    展开

    作者回复: 会去获取锁,但是获取锁后,会执行wait后的代码

    
     6
  • 木刻
    2019-04-02
    老师今天提到异步转同步,让我想到这两天看的zookeeper客户端源码,感觉应该也是这个机制,客户端同步模式下发送请求后会执行packet.wait,收到服务端响应后执行packet.notifyAll

    作者回复: 👍

    
     6
  • 杨鹏程baci
    2019-06-30
    老师好,关于我看到你说改成signalall()是优化了,但是我还是不明白如果用signal()可能会带来什么问题,具体优化体现在哪个方面,感觉从代码上出发,done是一个私有对象,也并不存在多个线程共享的问题,用signal()貌似也是够了的吧?
     1
     5
  • 右耳听海
    2019-04-28
    我看每个请求都会新建一个DefaultFuture,这个按道理应该只有一个线程阻塞,为什么需要signall
     1
     5
  • Binggle
    2019-04-02
    这是一对一的关系,肯定只需要 signal。每个线程都是相互独立的,lock 和 condition 也是各自独享的。

    作者回复: 一对一的关系用signalall也不是不可以

    
     5
  • ban
    2019-04-03
    老师,求指教
    DefaultFuturewhile这个类为什么要加 while(!isDone()) 这个条件,我看代码while里面加了done.await(timeout);是支持超时的,就是说设置5秒超时, if (isDone() || cur-start > timeout){,只要超过没有被signal()唤醒,那5秒就会自动唤醒,这时候就会在if (isDone() || cur-start > timeout){ 被校验通过,从而break,退出。这时候在加个while条件是不是没必要。
    还是说加个while条件是因为时间到点的时候自动唤醒后,Response可能是空,而且时间cur-start > timeout 不超时,所以才有必要进行while再一次判断isDone()是否有值。

    作者回复: while条件是编程范式,可以回去看管程原理,搞工程要多重防护。超时后当然很有可能resp是空的

    
     4
  • 代码搬运工
    2019-04-02
    回复:密码12345同学,如果是单例对象,response岂不是乱套了,每一个请求都对应自己的 response。另外singal()是合理的。因为每一个主线程对应一个子线程,不可能存在一个子线程对应多个请求。
    
     4
  • 拯救地球好累
    2019-07-24
    ---总结---
    1. 简单地讲,根据调用方是否需要等待结果,可以将程序的调用方式分为同步调用和异步调用
    2. 异步调用:调用方创建子线程并让子线程执行某一方法调用
    3. 异步方法:某一方法中创建了子线程执行逻辑,而让主线程返回

    ---思考题---
    DefaultFuture的某个实例并非单线程访问的,可能会有多个线程访问同一个,因此需要用SignalAll通知全部,避免没有通知到正确的线程(不知道DUBBO中DefaultFuture同一个实例会不会共享)
    展开
     1
     3
  • 苏格拉底23
    2019-06-23
    老师您好!

    有一个基本的问题不明白,如果每个request对应一个线程,似乎并没有用到共享的资源,那么为什么要加锁呢?

    作者回复: 这里只是利用管程实现线程的阻塞和唤醒

    
     3
  • 牧名
    2019-05-04
    DefaultFuture本质上只是一种future实现,所以理论上可以有多个线程同时持有同一个future并调用 get方法,如这时候使用signal()就有可能导致有些线程会请求超时
    ```java
    DefaultFuture future = currentClient.request(inv, timeout);
    for(int i=0; i< 10000; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(future.get().toString());
            }
        });
    }

    极客时间版权所有: https://time.geekbang.org/column/article/88487
    展开
     1
     3
  • 浅夏
    2019-07-26
    2.7.3版本以及不用lock和signal了
    
     2
  • ycfHH
    2019-05-06
    作为一个完全不懂dubbo的新人,我很好奇是什么bug能让signal改成signalAll,因为不管怎么看都感觉signal就已经可以了啊(虽然使用signalall也不错)

    作者回复: 优化而已

    
     2
  • 7月份的yi巴
    2019-04-03
    老师,有个疑问
    为什么要判断done!=null呢?这个条件不是永远为true吗。

    作者回复: 最新的代码他们已经改过来了😃

    
     2
我们在线,来聊聊吧