在python 进程、线程 (一)中简单的说过,CPython中的GIL使得同一时刻只能有一个线程运行,即并发执行。并且即使是多核CPU,GIL使得同一个进程中的多个线程也无法映射到多个CPU上运行,这么做最初是为了安全着想,慢慢的也成为了限制CPython性能的问题。
  
  就像是一个线程想要执行,就必须得到GIL,否则就不能拿到CPU资源。但是也不是说一个线程在拿到CPU资源后就一劳永逸,在执行的过程中GIL可能会释放并被其他线程获取,所以说其它的线程会与本线程竞争CPU资源。
  
  在understand GIL:http://www.dabeaz.com/python/UnderstandingGIL.pdf中有关于GIL释放和GIL的概要。
  
  多线程在python2中:当一个线程进行I/O的时候会释放锁,另外当ticks计数达到100(ticks可以看作是Python自身的一个计数器,也可对比着字节码指令理解,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整)。锁释放之后,就涉及到线程的调度,线程的锁进行,线程的切换。这是会消耗CPU资源,因此会造成程序性能问题和等待时延。特别是在CPU密集型代码时。
  
  但是对于多进程,GIL就无法限制,多个进程可以再多个CPU上运行,充分利用多核优势。事情往往是相对的,虽然可以充分利用多核优势,但是进程之间的切换却比线程的切换代价更高。
  
  所以选择多线程还是多进程,主要还是看怎样权衡代价,什么样的情况。
  
  1、CPU密集代码
  
  下面来利用斐波那契数列模拟CPU密集运算。
  
  def fib(n):
  
  # 求斐波那契数列的第n个值
  
  if n<=2:
  
  return 1
  
  return fib(n-1)+fib(n-2)
  
  <1>、多进程
  
  打印第25到35个斐波那契数,并计算程序运行时间
  
  import time
  
  from concurrent.futures import ThreadPoolExecutor, as_completed
  
  from concurrent.futures import ProcessPoolExecutor
  
  def fib(n):
  
  if n<=2:
  
  return 1
  
  return fib(n-1)+fib(n-2)
  
  if __name__ == "__main__":
  
  with ProcessPoolExecutor(3) as executor: # 使用进程池控制 每次执行3个进程
  
  all_task = [executor.submit(fib, (num)) for num in range(25,35)]
  
  start_time = time.time()
  
  for future in as_completed(all_task):
  
  data = future.result()
  
  print("exe result: {}".format(data))
  
  print("last time is: {}".format(time.time()-start_time))
  
  # 输出
  
  exe result: 75025
  
  exe result: 121393
  
  exe result: 196418
  
  exe result: 317811
  
  exe result: 514229
  
  exe result: 832040
  
  exe result: 1346269
  
  exe result: 2178309
  
  exe result: 3524578
  
  exe result: 5702887
  
  last time is: 4.457437038421631
  
  输出结果,每次打印三个exe result,总重打印十个结果,多进程运行时间为4.45秒
  
  <2>、多线程
  
  import time
  
  from concurrent.futures import ThreadPoolExecutor, as_completed
  
  from concurrent.futures import ProcessPoolExecutor
  
  def fib(n):
  
  if n<=2:
  
  return 1
  
  return fib(n-1)+fib(n-2)
  
  if __name__ == "__main__":
  
  with ThreadPoolExecutor(3) as executor: # 使用线程池控制 每次执行3个线程
  
  all_task = [executor.submit(fib, (num)) for num in range(25,35)]
  
  start_time = time.time()
  
  for future in as_completed(all_task):
  
  data = future.result()
  
  print("exe result: {www.gcyl152.com/ }".format(data))
  
  print("last time is: {}".format(time.time()-start_time))
  
  # 输出
  
  exe result: 121393
  
  exe result: 75025
  
  exe result: 196418
  
  exe result: 317811
  
  exe result: 514229
  
  exe result: 832040
  
  exe result: 1346269
  
  exe result: 2178309
  
  exe result: 3524578
  
  exe result: 5702887
  
  last time is: 7.3467772006988525
  
  最终程序运行时间为7.34秒
  
  程序的执行之间与计算机的性能有关,每天计算机的执行时间都会有差异。从上述结果中看显然多线程比多进程要耗费时间。这就是因为对于密集代码(密集运算,循环语句等),tick计数很快达到100,GIL来回的释放竞争,线程之间频繁切换,所以对于密集代码的执行中,多线程性能不如对进程。
  
  第一步导入依赖
  
  implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
  
  implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
  
  implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
  
  implementation 'cn.bingoogolapple:bga-banner:2.2.4@aar'
  
  创建BaseService
  
  import java.util.Map;
  
  import io.reactivex.Observable;
  
  import okhttp3.ResponseBody;
  
  import retrofit2.http.GET;
  
  import retrofit2.http.POST;
  
  import retrofit2.http.QueryMap;
  
  import retrofit2.http.Url;
  
  public interface BaseService {
  
  @GET
  
  Observable<ResponseBody> get(@Url String url, @QueryMap Map<String, String> map);
  
  @POST
  
  Observable<ResponseBody>www.gcyL157.com post(@Url www.michenggw.com String url, @QueryMap Map<String, String> map);
  
  工具类
  
  import java.io.IOException;
  
  import java.util.HashMap;
  
  import java.util.Map;
  
  import io.reactivex.Observer;
  
  import io.reactivex.www.yigouyule2.cn android.schedulers.AndroidSchedulers;
  
  import io.reactivex.disposables.Disposable;
  
  import io.reactivex.schedulers.Schedulers;
  
  import okhttp3.ResponseBody;
  
  import retrofit2.Retrofit;
  
  import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
  
  public class HttpHelper11 www.mhylpt.com{
  
  private BaseService mBaseService;
  
  public HttpHelper11(){
  
  Retrofit retrofit=new Retrofit.Builder()
  
  .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  
  .baseUrl("http://www.zhaoapi.cn/")
  
  .build();
  
  mBaseService=retrofit.create(BaseService.class);
  
  }
  
  //get请求
  
  public HttpHelper11 get(String url, Map<String,String> map){
  
  if(map==null){
  
  map=new HashMap<>();
  
  }
  
  mBaseService.get(url,map)
  
  .subscribeOn(Schedulers.io(www.mcyllpt.com/))
  
  .observeOn(AndroidSchedulers.mainThread())
  
  .subscribe(observer);
  
  return this;
  
  }
  
  //post请求
  
  public HttpHelper11 post(String url, Map<String,String> map){
  
  if(map==null){
  
  map=new HashMap<www.dfgjyl.cn>();
  
  }
  
  mBaseService.post(url,map)
  
  .subscribeOn(Schedulers.io())
  
  .observeOn(AndroidSchedulers.mainThread())
  
  .subscribe(observer);
  
  return this;
  
  }
  
  private Observer observer=new Observer<ResponseBody>() {
  
  @Override
  
  public void onSubscribe(Disposable d) {
  
  }
  
  @Override
  
  public void onNext(ResponseBody responseBody) {
  
  try {
  
  String data= responseBody.string();
  
  listener.success(data);
  
  } catch (IOException e) {
  
  e.printStackTrace(www.365soke.com);
  
  }
  
  }
  
  @Override
  
  public void onError(Throwable e) {
  
  String error= e.getMessage();
  
  listener.fail(error);
  
  }
  
  @Override
  
  public void onComplete() {
  
  }
  
  };
  
  private HttpListener listener;
  
  public void result(HttpListener listener){
  
  this.listener=listener;
  
  }
  
  public interface HttpListener {
  
  void success(String data);
  
  void fail(String error);
  
  }
  
  }

Retrofit+RxJava联网工具类的更多相关文章

  1. 记录一下关于在工具类中更新UI使用RunOnUiThread犯的极其愚蠢的错误

    由于Android中不能在子线程中更新ui,所以平时在子线程中需要更新ui时可以使用Android提供的RunOnUiThread接口,但是最近在写联网工具类的时候,有时候会出现联网异常,这个时候为了 ...

  2. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  3. 【Android - 框架】之Retrofit+RxJava的使用

    前几天分别对Retrofit和RxJava进行了总结,这个帖子打算把Retrofit结合RxJava使用的方法总结以下.有还不了解Retrofit或RxJava的朋友可以参考下面的帖子学习~ [And ...

  4. 基于Retrofit+RxJava的Android分层网络请求框架

    目前已经有不少Android客户端在使用Retrofit+RxJava实现网络请求了,相比于xUtils,Volley等网络访问框架,其具有网络访问效率高(基于OkHttp).内存占用少.代码量小以及 ...

  5. IP工具类-自己动手做个ip解析器

    IP工具类-自己动手做个ip解析器 一.资料准备 导入依赖包:

  6. 利用Retrofit, RxJava获取网络内容

    Retrofit & RxJava 关于如何使用Retrofit和RxJava请阅读参考中的两篇文章. Retrofit处理数据 Retrofit是在什么时候处理从网络中获取到的json数据的 ...

  7. Android开源项目发现--- 工具类快速开发篇(持续更新)

    1. Guava Google的基于java1.6的类库集合的扩展项目 包括collections, caching, primitives support, concurrency librarie ...

  8. Android开源项目发现--- 工具类数据库ORM篇(持续更新)

    orm的db工具类,简化建表.查询.更新.插入.事务.索引的操作 1. greenDAO Android Sqlite orm的db工具类 项目地址:https://github.com/greenr ...

  9. Android开源项目发现--- 工具类网络相关篇(持续更新)

    1. Asynchronous Http Client for Android Android异步Http请求 项目地址:https://github.com/loopj/android-async- ...

随机推荐

  1. Linux上不了网——wget无法解析主机

    很有可能是网关和域名服务器没有设置 1.设置网关 netstat -rn #查看网关配置情况 [hadoop@slave1 ~]$ route -n Kernel IP routing table D ...

  2. php使用json_decode返回NULL

    php5.2以后自带json_decode函数,但是对json文本串的格式要求非常严格. 很可能使用该函数得到的返回值是NULL 可以使用使用json_last_error()函数获取到的返回值来帮助 ...

  3. spring mvc支持跨域请求

    @WebFilter(urlPatterns = "/*", filterName = "corsFilter") public class CorsFilte ...

  4. Spring源码:Spring IoC容器加载过程(1)

    Spring源码版本:4.3.23.RELEASE 一.加载过程概览 Spring容器加载过程可以在org.springframework.context.support.AbstractApplic ...

  5. poj3616 Milking Time

    思路: dp. 实现: #include <iostream> #include <cstdio> #include <algorithm> using names ...

  6. DOM编程练习(慕课网题目)

    编程练习 制作一个表格,显示班级的学生信息. 要求: 1. 鼠标移到不同行上时背景色改为色值为 #f2f2f2,移开鼠标时则恢复为原背景色 #fff 2. 点击添加按钮,能动态在最后添加一行 3. 点 ...

  7. Arduino中数据类型转换 float/double转换为char 亲测好使,dtostrf()函数

    如何轻松玩转Arduino单片机,当我在进行数据转换的时候,遇到了问题,尝试了C语言和C++中的好多函数,都没有达到将float型数据转换为char型的目的.苦苦查阅资料后,终于找到了一个大神级函数! ...

  8. 第一次向nodeclub提交修改

    今天第一次向nodeclub提交了两个修改,两个修改都是涉及部分浏览器的兼容性的. Manager很快合并了我的修改,好开森.晚上又重新回炉了一下git的日常操作,将git部分操作整理了一下写于此博. ...

  9. 洛谷 P2319 [HNOI2006]超级英雄

    题目描述 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确回答一 ...

  10. 应用程序员眼中的数据库管理系统:API+数据库语言

    应用程序员眼中的数据库管理系统:API+数据库语言 sqlite3_open_v2 https://www.cnblogs.com/cchust/p/5121559.html