线程与线程池的应用

简介: 异步任务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方式使用失误 基本只会导致其一线程瘫痪,更易于查找 修复。

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

如有纰漏 敬请斧正

目录
相关文章
|
2天前
|
存储 监控 Java
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
89 60
【Java并发】【线程池】带你从0-1入门线程池
|
1月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
20天前
|
安全 Java C#
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
3月前
|
Prometheus 监控 Cloud Native
JAVA线程池监控以及动态调整线程池
【10月更文挑战第22天】在 Java 中,线程池的监控和动态调整是非常重要的,它可以帮助我们更好地管理系统资源,提高应用的性能和稳定性。
279 64
|
3月前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
139 38
|
3月前
|
缓存 Java 开发者
Java多线程并发编程:同步机制与实践应用
本文深入探讨Java多线程中的同步机制,分析了多线程并发带来的数据不一致等问题,详细介绍了`synchronized`关键字、`ReentrantLock`显式锁及`ReentrantReadWriteLock`读写锁的应用,结合代码示例展示了如何有效解决竞态条件,提升程序性能与稳定性。
418 6
|
2月前
|
监控 Java 数据库连接
Java线程管理:守护线程与用户线程的区分与应用
在Java多线程编程中,线程可以分为守护线程(Daemon Thread)和用户线程(User Thread)。这两种线程在行为和用途上有着明显的区别,了解它们的差异对于编写高效、稳定的并发程序至关重要。
68 2
|
3月前
|
数据采集 存储 数据处理
Python中的多线程编程及其在数据处理中的应用
本文深入探讨了Python中多线程编程的概念、原理和实现方法,并详细介绍了其在数据处理领域的应用。通过对比单线程与多线程的性能差异,展示了多线程编程在提升程序运行效率方面的显著优势。文章还提供了实际案例,帮助读者更好地理解和掌握多线程编程技术。
|
3月前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
105 8
|
3月前
|
存储 监控 安全
深入理解ThreadLocal:线程局部变量的机制与应用
在Java的多线程编程中,`ThreadLocal`变量提供了一种线程安全的解决方案,允许每个线程拥有自己的变量副本,从而避免了线程间的数据竞争。本文将深入探讨`ThreadLocal`的工作原理、使用方法以及在实际开发中的应用场景。
128 2