Fresco Fbcore源码分析_executor(一)

来源:互联网 发布:论文中英文翻译软件 编辑:程序博客网 时间:2024/05/20 13:10

Fbcore简介

Fbcore包含两大模块,一个是common 另一个是datasource ,它主要提供了Fresco 框架通用的接口和相关的API。这些API被Imagepipeline 和 drawee大量的使用

Executor功能分析

Executor类简介

1.CallerThreadExecutor.java

 CallerThreadExecutor是一个单例类,它将线程的执行过程进行了封装,所有的线程的运行都可以通过下面的方法来运行,简单来说他是一个线程的执行者
public void execute(Runnable command) {    command.run();  }

2.ConstrainedExecutorService.java

   ConstrainedExecutorService主要是用来处理多线程的并发操作,它同时也支持自定义并发线程的个数,接下来上代码

构造方法分析

  public ConstrainedExecutorService(      String name,      int maxConcurrency,      Executor executor,      BlockingQueue<Runnable> workQueue) {//这里使用BlockingQueue是为了保证线程不会被阻塞,它基于生产者消费者模型来实现,当队列里线程满的时候他会阻止线程的进入,当队列空的时候,他会阻止从队列里面取出线程    if (maxConcurrency <= 0) {      throw new IllegalArgumentException("max concurrency must be > 0");    }    mName = name;    mExecutor = executor;    mMaxConcurrency = maxConcurrency;//代表最大同时运行线程的个数    mWorkQueue = workQueue;    mTaskRunner = new Worker();//Workr是一个线程,它实现了从队列里拿出一个线程并执行它,同时会实时调整mPendingWorkers 的个数    mPendingWorkers = new AtomicInteger(0);//Pending work 代表正在从队列里出来的正在执行的线程的个数    mMaxQueueSize = new AtomicInteger(0);//代表线成队列的最大值  }

接下来看看这个类主要做了什么?
这个类主要通过下面两个方法来工作:execute 和 startWorkerIfNeeded,下面是具体的分析:

public void execute(Runnable runnable) {    if (runnable == null) {      throw new NullPointerException("runnable parameter is null");    }    if (!mWorkQueue.offer(runnable)) {//将这个线程添加到队列里,如果失败则抛出异常      throw new RejectedExecutionException(          mName + " queue is full, size=" + mWorkQueue.size());    }    final int queueSize = mWorkQueue.size();//获取队列的大小    final int maxSize = mMaxQueueSize.get();//获取自定义的队列的最大值    if ((queueSize > maxSize) && mMaxQueueSize.compareAndSet(maxSize, queueSize)) {      FLog.v(TAG, "%s: max pending work in queue = %d", mName, queueSize);    } // else, there was a race and another thread updated and logged the max queue size    startWorkerIfNeeded();  }
 private void startWorkerIfNeeded() {    // Perform a compare-and-swap retry loop for synchronization to make sure we don't start more    // workers than desired.    int currentCount = mPendingWorkers.get();//获取当前正在运行的线程的个数    while (currentCount < mMaxConcurrency) {//当运行的线程个数小于最大并发线程数的时候,循环从队列里面获取线程并运行      int updatedCount = currentCount + 1;      if (mPendingWorkers.compareAndSet(currentCount, updatedCount)) {//更新正在运行的线程的个数        // Start a new worker.        FLog.v(TAG, "%s: starting worker %d of %d", mName, updatedCount, mMaxConcurrency);        mExecutor.execute(mTaskRunner);//开始运行从队列里取出来的线程并实时更新正在运行的线程的个数        break;      }      // else: compareAndSet failed due to race; snapshot the new count and try again      FLog.v(TAG, "%s: race in startWorkerIfNeeded; retrying", mName);      currentCount = mPendingWorkers.get();//获取当前正在运行的线程的个数    }  }

接下来我们看看mTaskRunner都干了什么?

  private class Worker implements Runnable {    @Override    public void run() {      try {        Runnable runnable = mWorkQueue.poll();//从队列中获取并删除第一个元素        if (runnable != null) {          runnable.run();//获取到的线程如果不为空则执行该线程        } else {          // It is possible that a new worker was started before a previously started worker          // de-queued its work item.          FLog.v(TAG, "%s: Worker has nothing to run", mName);        }      } finally {        int workers = mPendingWorkers.decrementAndGet();//当线程运行完了之后,正在运行的线程数减一        if (!mWorkQueue.isEmpty()) {          startWorkerIfNeeded();//如果队列不为空的话,判断是否需要从队列中获取线程并执行        } else {          FLog.v(TAG, "%s: worker finished; %d workers left", mName, workers);        }      }    }  }

接下来我们以流程图来看下整个逻辑的处理过程

Created with Raphaël 2.1.0http://www.google.comStarthttp://www.google.com添加线程到队列里更新队列的大小获取当前正在运行的线程个数将正在运行的线程数和最大并发线程数进行比较http://www.google.com大于or 小于?http://www.google.comhttp://www.google.comEndhttp://www.google.com将正在运行线程个数加1从队列里取出线程并运行当线程结束是将正在运行线程个数减1判断队列是否为空http://www.google.comyesor no?http://www.google.com跳出循环yesnoyesno

3.DefaultSerialExecutorService.java

DefaultSerialExecutorService默认实现了SerialExecutorService接口并继承ConstrainedExecutorService,他将会按先进先出的顺序执行队列中的任务

0 0
原创粉丝点击