热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android开发经验谈:并发编程(线程与线程池)(推荐)

一、线程 在Android开发中,你不可能都在主线程中开发,毕竟要联网,下载数据,保存数据等操作,当然这就离不开线程。 (当然你可以在A

一、线程

在Android开发中,你不可能都在主线程中开发,毕竟要联网,下载数据,保存数据等操作,当然这就离不开线程。

(当然你可以在Android4.0以前的手机里在主线程请求网络,我最早开发的时候,用的手机比较古老。。。)

在Android中你可以随意创建线程,于是就会造成线程不可控,内存泄漏,创建线程消耗资源,线程太多了消耗资源等问题。
具体线程怎么创建我就不在文章里描述了,毕竟这主要将并发编程。。。。

大家知道线程不可控就好了。。。于是就需要对线程进行控制,防止一系列问题出现,这就用到了如下要讲的东西。

二、线程池

线程池:顾名思义,就是放线程的大池子。

如何创建一个线程池?

先说说几个系统的线程池:

  1. FixedThreadPool 创建定长线程的线程池
  2. CachedThreadPool 需要的时候建立新的线程,超时线程销毁
  3. SingleThreadPool 单个线程的线程池
  4. ScheduledThreadPool 可以定时的线程池,创建周期性的任务

这几个线程池不做多余阐述,因为这些线程池的原理都与我下面要讲的有关。。。。

如何自定义线程池(先来了解几个必须知道的参数):

corePoolSize:

核心线程池大小,线程池中主要工作的线程的多少。

maximumPoolSize:

线程池最大线程数。

keepAliveTime:

空闲线程可保持的时间是多久,如果你启用了allowCoreThreadTimeOut方法,你的线程池里的空闲线程在这个时间段后会自动销毁,如果没启用,则只要不超过corePoolSize,空闲线程也不会销毁。

Unit:

keepAliveTime的时间单位

workQueue:

阻塞队列,当任务达到corePoolSize,就会被放入这个队列

常见几种BlockingQueue实现

  1. ArrayBlockingQueue :  有界的数组队列
  2. LinkedBlockingQueue : 可支持有界/无界的队列,使用链表实现
  3. PriorityBlockingQueue : 优先队列,可以针对任务排序
  4. SynchronousQueue : 队列长度为1的队列,和Array有点区别就是:client thread提交到block queue会是一个阻塞过程,直到有一个worker thread连接上来poll task。

threadFactory:

线程工厂,主要用来创建线程;

handler:

表示当拒绝处理任务时的策略,也就是参数maximumPoolSize达到后丢弃处理的方法。有以下四种取值:

  1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
  2. ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
  3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
  4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

用户也可以实现接口RejectedExecutionHandler定制自己的策略。

代码展示:

//线程工厂
public class TaskThreadFactory implements ThreadFactory {

 private final AtomicInteger mThreadNumber = new AtomicInteger(1);



 private final String mNamePrefix;

 TaskThreadFactory(String name) {
  mNamePrefix = name + "#";
 }

 public Thread newThread(Runnable r) {
  Thread t = new Thread(r,mNamePrefix + mThreadNumber.getAndIncrement());

//  if (t.isDaemon())
//   t.setDaemon(false);
//
//  if (t.getPriority() != Thread.NORM_PRIORITY)
//   t.setPriority(Thread.NORM_PRIORITY);

  return t;
 }
}

//重写runnable
public class PRunnable implements Runnable {

 public static final int HIGH = 1;//优先级高
 public static final int NORMAL = 2;//优先级中等
 public static final int LOW = 3;//优先级低
 @IntDef({HIGH,NORMAL,LOW})
 @Retention(RetentionPolicy.SOURCE)
 public @interface Priority{}

 public final int priority;
 private final Runnable runnable;
 public int serial;

 public PRunnable(Runnable runnable){
  this(NORMAL,runnable);
 }

 public PRunnable(@Priority int priority,Runnable runnable){
  this.priority = priority;
  this.runnable = runnable;
 }

 @Override
 public void run() {
  if (runnable != null) {
   runnable.run();
  }
 }

 /**
  * 线程队列方式 先进先出
  * @param r1
  * @param r2
  * @return
  */
 public static final int compareFIFO(PRunnable r1, PRunnable r2) {
  int result = r1.priority-r2.priority;
  return result==0?r1.serial-r2.serial:result;
 }

 /**
  * 线程队列方式 后进先出
  * @param r1
  * @param r2
  * @return
  */
 public static final int compareLIFO(PRunnable r1, PRunnable r2) {
  int result = r1.priority-r2.priority;
  return result==0?r2.serial-r1.serial:result;
 }
}

//线程池实现
public class TaskExecutor implements Executor {

 private final static int QUEUE_INIT_CAPACITY = 20;

 private static final int CORE = 3;

 private static final int MAX = 5;

 private static final int TIMEOUT = 30 * 1000;

 private AtomicInteger SERIAL = new AtomicInteger(0);//主要获取添加任务

 public static class Config {
  public int core;

  public int max;

  public int timeout;

  public boolean allowCoreTimeOut;

  public boolean fifo;

  public Config(int core, int max, int timeout, boolean allowCoreTimeOut,boolean fifo) {
   this.core = core;
   this.max = max;
   this.timeout = timeout;
   this.allowCoreTimeOut = allowCoreTimeOut;
   this.fifo = fifo;
  }
 }

 public static Config defaultCOnfig= new Config(CORE, MAX, TIMEOUT, true,true);


 private final String name;

 private final Config config;

 private ExecutorService service;

 public TaskExecutor(String name) {
  this(name, defaultConfig);
 }

 public TaskExecutor(String name, Config config) {
  this(name, config, true);
 }

 public TaskExecutor(String name, Config config, boolean startup) {
  this.name = name;
  this.cOnfig= config;

  if (startup) {
   startup();
  }
 }

 public void startup() {
  synchronized (this) {
   if (service != null && !service.isShutdown()) {
    return;
   }

   service = createExecutor(config);
  }
 }

 public void shutdown() {
  ExecutorService executor = null;

  synchronized (this) {
   // 交换变量
   if (service != null) {
    executor = service;
    service = null;
   }
  }

  if (executor != null) {
   // 停止线程
   if (!executor.isShutdown()) {
    executor.shutdown();
   }

   // 回收变量
   executor = null;
  }
 }

 private void executeRunnable(PRunnable runnable) {
  synchronized (this) {
   if (service == null || service.isShutdown()) {
    return;
   }
   runnable.serial = SERIAL.getAndIncrement();
   service.execute(runnable);
  }
 }

 @Override
 public void execute(Runnable runnable) {
  if (runnable instanceof PRunnable) {
   executeRunnable((PRunnable) runnable);
  }else{
   executeRunnable(new PRunnable(runnable));
  }
 }

 public Future<&#63;> submit(Runnable runnable) {
  synchronized (this) {
   if (service == null || service.isShutdown()) {
    return null;
   }
   if (runnable instanceof PRunnable) {
    ((PRunnable) runnable).serial = SERIAL.getAndIncrement();
    return service.submit(runnable);
   }else{
    PRunnable pRunnable = new PRunnable(runnable);
    pRunnable.serial = SERIAL.getAndIncrement();
    return service.submit(pRunnable);
   }
  }
 }

 public void execute(Runnable runnable, @PRunnable.Priority int priority) {
  executeRunnable(new PRunnable(priority,runnable));
 }

 private ExecutorService createExecutor(Config config) {
  ThreadPoolExecutor service = new ThreadPoolExecutor(config.core, config.max, config.timeout,
    TimeUnit.MILLISECONDS, new PriorityBlockingQueue(QUEUE_INIT_CAPACITY, config.fifo &#63; mQueueFIFOComparator : mQueueLIFOComparator),
    new TaskThreadFactory(name), new ThreadPoolExecutor.DiscardPolicy());

  allowCoreThreadTimeOut(service, config.allowCoreTimeOut);

  return service;
 }

 public boolean isBusy() {
  synchronized (this) {
   if (service == null || service.isShutdown()) {
    return false;
   }
   if(service instanceof ThreadPoolExecutor){
    ThreadPoolExecutor tService = (ThreadPoolExecutor) service;
    return tService.getActiveCount() >= tService.getCorePoolSize();
   }
   return false;
  }
 }

 private static final void allowCoreThreadTimeOut(ThreadPoolExecutor service, boolean value) {
  if (Build.VERSION.SDK_INT >= 9) {
   allowCoreThreadTimeOut9(service, value);
  }
 }

 @TargetApi(9)
 private static final void allowCoreThreadTimeOut9(ThreadPoolExecutor service, boolean value) {
  service.allowCoreThreadTimeOut(value);
 }


 Comparator mQueueFIFOComparator = new Comparator() {

  @Override
  public int compare(Runnable lhs, Runnable rhs) {
   PRunnable r1 = (PRunnable) lhs;
   PRunnable r2 = (PRunnable) rhs;

   return PRunnable.compareFIFO(r1, r2);
  }
 };

 Comparator mQueueLIFOComparator = new Comparator() {

  @Override
  public int compare(Runnable lhs, Runnable rhs) {
   PRunnable r1 = (PRunnable) lhs;
   PRunnable r2 = (PRunnable) rhs;

   return PRunnable.compareLIFO(r1, r2);
  }
 };

}

以上所述是小编给大家介绍的Android开发经验谈:并发编程(线程与线程池)详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 本文介绍如何通过SSH协议使用Xshell远程连接到Ubuntu系统。为了实现这一目标,需要确保Ubuntu系统已安装并配置好SSH服务器,并保证网络连通性。 ... [详细]
  • 优化局域网SSH连接延迟问题的解决方案
    本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • 从零开始构建完整手机站:Vue CLI 3 实战指南(第一部分)
    本系列教程将引导您使用 Vue CLI 3 构建一个功能齐全的移动应用。我们将深入探讨项目中涉及的每一个知识点,并确保这些内容与实际工作中的需求紧密结合。 ... [详细]
  • moment 国际化设置中文语言 (全局) 及使用示例 ... [详细]
  • 深入解析 Spring Security 用户认证机制
    本文将详细介绍 Spring Security 中用户登录认证的核心流程,重点分析 AbstractAuthenticationProcessingFilter 和 AuthenticationManager 的工作原理。通过理解这些组件的实现,读者可以更好地掌握 Spring Security 的认证机制。 ... [详细]
  • 本文介绍如何在现有网络中部署基于Linux系统的透明防火墙(网桥模式),以实现灵活的时间段控制、流量限制等功能。通过详细的步骤和配置说明,确保内部网络的安全性和稳定性。 ... [详细]
  • Git管理工具SourceTree安装与使用指南
    本文详细介绍了Git管理工具SourceTree的安装、配置及团队协作方案,旨在帮助开发者更高效地进行版本控制和项目管理。 ... [详细]
  • 本文详细介绍如何在Linux系统中配置SSH密钥对,以实现从一台主机到另一台主机的无密码登录。内容涵盖密钥对生成、公钥分发及权限设置等关键步骤。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • Python 工具推荐 | PyHubWeekly 第二十一期:提升命令行体验的五大工具
    本期 PyHubWeekly 为大家精选了 GitHub 上五个优秀的 Python 工具,涵盖金融数据可视化、终端美化、国际化支持、图像增强和远程 Shell 环境配置。欢迎关注并参与项目。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
author-avatar
私受他
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有