线程与线程池的应用

简介: 异步任务AsyncTask 源码 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java最近在Android开发上遇到线程遇到诸多问题,特此记录下。

异步任务AsyncTask 源码 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java

最近在Android开发上遇到线程遇到诸多问题,特此记录下。也希望能为诸君贡献一二。

Code一版

直接使用new Thread


        new Thread(new Runnable() {
                @Override
                public void run() {
                    doSomething();//执行代码(耗时等 数据库操作等)
                }
            }).start();

很明显的弊端,Code中太多地方需要线程的地方,new 了无数个线程。
1.每次new Thread新建对象性能差
2. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,即可能占用过多的系统资源导致死机
3.缺乏更多功能,比如定时执行,定期执行,线程中断。
总之最后很扎心,而且你能想象这放在一个性能很差的Android机里面运行么~~


Code二版

使用定义的线程池


先来个我定义的

/**
 * 线程池管理(线程统一调度管理)
 */
public final class ThreadPoolManager {

    public static class ThreadPoolProxy {
        ThreadPoolExecutor mExecutor;
        private int mCorePoolSize;
        private int mMaximumPoolSize;
        /**
         * @param corePoolSize    核心池的大小
         * @param maximumPoolSize 最大线程数
         */
        public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
            mCorePoolSize = corePoolSize;
            mMaximumPoolSize = maximumPoolSize;
        }

        /**
         * 初始化ThreadPoolExecutor
         * 双重检查加锁,只有在第一次实例化的时候才启用同步机制,提高了性能
         */
        private void initThreadPoolExecutor() {
            if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                synchronized (ThreadPoolProxy.class) {
                    if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                        long keepAliveTime = 3000;
                        TimeUnit unit = TimeUnit.MILLISECONDS;
                        BlockingQueue workQueue = new LinkedBlockingDeque<>();
                        ThreadFactory threadFactory = Executors.defaultThreadFactory();
                        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

                        mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
                                threadFactory, handler);
                    }
                }
            }
        }
        /**
         执行任务和提交任务的区别?
         1.有无返回值
         execute->没有返回值
         submit-->有返回值
         2.Future的具体作用?
         1.有方法可以接收一个任务执行完成之后的结果,其实就是get方法,get方法是一个阻塞方法
         2.get方法的签名抛出了异常===>可以处理任务执行过程中可能遇到的异常
         */
        /**
         * 执行任务
         */
        public void execute(Runnable task) {
            initThreadPoolExecutor();
            mExecutor.execute(task);
        }

        /**
         * 提交任务
         */
        public Future submit(Runnable task) {
            initThreadPoolExecutor();
            return mExecutor.submit(task);
        }

        /**
         * 移除任务
         */
        public void remove(Runnable task) {
            initThreadPoolExecutor();
            mExecutor.remove(task);
        }
    }

    /**
     * 线程池工厂类
     * Created by Samson on 2018/2/11.
     * 使用方法
     * ThreadPoolProxyFactory .getNormalThreadPoolProxy().execute(Runnable);
     */

    public static class ThreadPoolProxyFactory {
        private static ThreadPoolProxy mNormalThreadPoolProxy;
        private static ThreadPoolProxy mDownLoadThreadPoolProxy;

        /**
         * 得到普通线程池代理对象mNormalThreadPoolProxy
         */
        public static ThreadPoolProxy getNormalThreadPoolProxy() {
            if (mNormalThreadPoolProxy == null) {
                synchronized (ThreadPoolProxyFactory.class) {
                    if (mNormalThreadPoolProxy == null) {
                        mNormalThreadPoolProxy = new ThreadPoolProxy(10 , 10);
                    }
                }
            }
            return mNormalThreadPoolProxy;
        }
        /**
         * 下载专用
         * 得到下载线程池代理对象mDownLoadThreadPoolProxy
         */
        public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
            if (mDownLoadThreadPoolProxy == null) {
                synchronized (ThreadPoolProxyFactory.class) {
                    if (mDownLoadThreadPoolProxy == null) {
                        mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
                    }
                }
            }
            return mDownLoadThreadPoolProxy;
        }
    }
}

如何使用:

ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
                  .execute(new Runnable() {
                                  @Override
                                    public void run() {
                                          doSomething();
                                     }
                 });
-----------------------------------------lambda
ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
        .execute(() -> {doSomething();});

Code三版

手动控制版线程池(将所有事务分类放在规定的线程中执行,(未不同类别的事务规定不同的线程))


/**
 * 本地数据处理和耗时处理用不同线程处理
 */

public class ThreadPoolUtil {

    private List<Run> runList = new ArrayList<>();
    private List<Run> runListTemp = new ArrayList<>();
    private Thread thread = null;

    public interface Run {
        void run();
    }

    private ThreadPoolUtil() {
        init();
    }

    private void init() {
        if (thread == null) {
            thread = new Thread(() -> {
                for (; ; ) {
                    synchronized (lock) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    dealRun();
                }
            });
            thread.start();
        }
    }

    private final Object lock = new Object();
    private static ThreadPoolUtil _INSTANCESEND = null;
    private static ThreadPoolUtil _INSTANCESERVER = null;
    private static ThreadPoolUtil _INSTANCENORMAL = null;

    /**
     *  发消息
     * @return
     */
    public static ThreadPoolUtil getSendMsgInstance() {
        if (_INSTANCESEND == null) {
            _INSTANCESEND = new ThreadPoolUtil();
        }
        return _INSTANCESEND;
    }
    /**
     *  收消息
     * @return
     */
    public static ThreadPoolUtil getGetMsgInstance() {
        if (_INSTANCESERVER == null) {
            _INSTANCESERVER = new ThreadPoolUtil();
        }
        return _INSTANCESERVER;
    }
    /**
     *  普通通用消息
     * @return
     */
    public static ThreadPoolUtil getNormalInstance() {
        if (_INSTANCENORMAL == null) {
            _INSTANCENORMAL = new ThreadPoolUtil();
        }
        return _INSTANCENORMAL;
    }


    public void addRun(Run run) {
        runListTemp.add(run);
        synchronized (lock) {
            runList.addAll(runListTemp);
            runListTemp.clear();
            lock.notify();
        }
    }

    private Run getRun() {
        if (runList.size() <= 0) {
            return null;
        }
        Run run = null;
        synchronized (lock) {
            run = runList.get(0);
            runList.remove(0);
        }
        return run;
    }

    private void dealRun() {
        try {
            for (Run run = getRun(); (run) != null; ) {
                run.run();
                run = getRun();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如何使用:不同的分类可 get 不同的线程来处理。

ThreadPoolUtil.getNormalInstance().addRun(new ThreadPoolUtil.Run() {
                @Override
                public void run() {
                     doSomething();
                }
            });
-----------------------------------------lambda
ThreadPoolUtil.getNormalInstance().addRun(() ->{
                doSomething();
            });

2,3两种方式 区别

2方式一旦有线程操作失误可能会导致全线线程瘫痪,导致整个线程池无法正常的运行下去,
3方式使用失误 基本只会导致其一线程瘫痪,更易于查找 修复。

至于其他优势 仍在探究中...

如有纰漏 敬请斧正

目录
相关文章
|
1月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
108 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
2天前
|
监控 Java
在实际应用中选择线程异常捕获方法的考量
【10月更文挑战第15天】选择最适合的线程异常捕获方法需要综合考虑多种因素。没有一种方法是绝对最优的,需要根据具体情况进行权衡和选择。在实际应用中,还需要不断地实践和总结经验,以提高异常处理的效果和程序的稳定性。
10 3
|
6天前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
22 4
|
6天前
|
数据采集 存储 Java
Crawler4j在多线程网页抓取中的应用
Crawler4j在多线程网页抓取中的应用
|
13天前
|
数据挖掘 程序员 调度
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
21 3
|
13天前
|
Java 数据处理 数据库
Java多线程的理解和应用场景
Java多线程的理解和应用场景
39 1
|
13天前
|
Dubbo Java 应用服务中间件
剖析Tomcat线程池与JDK线程池的区别和联系!
剖析Tomcat线程池与JDK线程池的区别和联系!
剖析Tomcat线程池与JDK线程池的区别和联系!
|
1月前
|
Java
直接拿来用:进程&进程池&线程&线程池
直接拿来用:进程&进程池&线程&线程池
|
1月前
|
负载均衡 Java 调度
探索Python的并发编程:线程与进程的比较与应用
本文旨在深入探讨Python中的并发编程,重点比较线程与进程的异同、适用场景及实现方法。通过分析GIL对线程并发的影响,以及进程间通信的成本,我们将揭示何时选择线程或进程更为合理。同时,文章将提供实用的代码示例,帮助读者更好地理解并运用这些概念,以提升多任务处理的效率和性能。
51 3
|
1月前
|
Java 开发者
Java中的多线程基础与应用
【9月更文挑战第22天】在Java的世界中,多线程是一块基石,它支撑着现代并发编程的大厦。本文将深入浅出地介绍Java中多线程的基本概念、创建方法以及常见的应用场景,帮助读者理解并掌握这一核心技术。