任务模型 - 北邙山之光的博客

现实问题

特殊的刷新界面需求如下:

  1. 请求后台,返回数据中包含若干个链接link0、link1···
  2. 访问各个link等待结果
  3. 如果时间超过400ms或者各个link都请求成功,那么才刷新当前界面

总结一下就是,要么等400ms,要么各个请求都成功了,才去刷新界面。

何解

这个需求发生在客户端,要写一个特殊的加载器的逻辑。
经过查阅,我发现Java各种获取线程执行结果的API都是线程阻塞的,比如FutureTask(也可能我没找到···)
再比如CountDownLatch,在等待各个线程执行结束和超时的时候,当前线程也是阻塞的。

  • 自己写一个线程池,一个计数器,回调

    每个任务开启子线程,然后成功回调到主线程,有一个计数器在计算完成任务数
    同时,在执行子线程任务时,主线程执行一个延时400ms的任务(runnable),如果任务先结束就取消掉这个400ms任务,否则执行400ms任务。
    这里有个状态问题,就是只能有一个被执行,要么是全完成,要么是400ms的任务,所以还需要一个状态值控制这两个互斥。

    伪代码:

    mTimer = new Runnable() {
          @Override
          public void run() {
              if (!mHasRefreshed) {
                  //刷新
              }
          }
      };
    
    mThreadPool.execute(task);
    mHandler.postDelayed(mTimer, 400);
    taskManager.bindCallback(new Callback(){
      @Override
      public void onTaskSuccess() {
          counter++;
          if (!mHasRefreshed&&counter==tasks.size()) {
              //刷新
          }
    });
    
    
    大专栏  任务模型 - 北邙山之光的博客">//task中,每个任务成功
    Handler mTaskHandler = new Handler(Looper.getMainLooper());
    mTaskHandler.post(new Runnable(){
      @Override
      public void run() {
          if (!mHasRefreshed) {
              callback.onTaskSuccess();
          }
      }
    });
    

    大致思路如此,不必纠结细节

  • 用封装好的Java API

    比如CountDownLatch

    CountDownLatch countDownLatch = new CountDownLatch(tasks.size());
    for(int i = 0; i < tasks.size(); i++){
        mThreadPool.execute(tasks.get(i));
    }
    countDownLatch.await(200,TimeUnit.MILLISECONDS);
    
    //task中
    countDownLatch.countDown();
    

    但是会阻塞线程哦,所以要放到子线程,然后回调到主线程

不知道最优方案是啥

不知道后台工程师,在后台遇到类似逻辑怎么写,这种获取线程执行结果的,都是阻塞线程的,但是在客户端,主线程是不可被阻塞的。




猜你喜欢

转载自www.cnblogs.com/sanxiandoupi/p/11711258.html