Android 线程池的使用 --ThreadPoolExecutor 基本线程池

91 阅读2分钟

在任务众多的情况下,系统要为每一个任务创建一个线程,而任务执行完毕后会销毁每一个线程,所以会造成线程频繁地创建与销毁。从而会占用大量资源,多个线程在抢夺资源中会造成UI线程的卡顿,同时多个线程频繁地销毁,会频繁地调用GC机制,这会使性能降低,又非常耗时。这个时候我们就需要统一管理这些线程!

为什么使用线程池?

缺陷:

  • 在任务众多的情况下,系统要为每一个任务创建一个线程,而任务执行完毕后会销毁每一个线程,所以会造成线程频繁地创建与销毁。
  • 多个线程频繁地创建会占用大量的资源,并且在资源竞争的时候就容易出现问题,同时这么多的线程缺乏一个统一的管理,容易造成界面的卡顿。
  • 多个线程频繁地销毁,会频繁地调用GC机制,这会使性能降低,又非常耗时。

好处:

  • 对多个线程进行统一地管理,可提供定时执行及指定间隔循环执行的功能
  • 有效控制线程池的最大并发数,避免大量线程抢占资源出现的问题。
  • 对线程进行复用,线程在执行完任务后不会立刻销毁,而会等待另外的任务,这样就不会频繁地创建、销毁线程和调用GC。

几种常见的线程池

1:ThreadPoolExecutor 基本线程池

2:FixedThreadPool (执行长期的任务,性能好很多)

3:CachedThreadPool (适用于有大量需要立即执行的耗时少的任务的情况)

4:SingleThreadPool(一个任务一个任务执行的场景是的单个的FixedThreadPool )

5:ScheduledThreadPool(周期性执行任务的场景)

以基本线程池为例:

有10个耗时任务,放进线程池,执行

package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ThreadPoolProxyFactory t=new ThreadPoolProxyFactory();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            t.submit(new Runnable() {
                public void run() {
                    try {
                        // 打印正在执行的线程信息
                        Log.e("TAG",Thread.currentThread().getName()+ "正在被执行,第"+ index+"次");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

}

创建一个线程池(ThreadPoolProxyFactory类)

package com.example.myapplication;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolProxyFactory {

    //创建基本线程池
    static ThreadPoolExecutor mExecutor;

    public static ThreadPoolExecutor initThreadPoolExecutor(){
        if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()){
            synchronized (ThreadPoolProxyFactory.class){
                if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()){
                    long keepAliveTime = 0;
                    TimeUnit unit = TimeUnit.MILLISECONDS;
                    BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue();
                    ThreadFactory threadFactory = Executors.defaultThreadFactory();
                    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
                    mExecutor=new ThreadPoolExecutor(5,5,keepAliveTime,unit,workQueue,threadFactory,handler);
                }
            }
        }
        return mExecutor;
    }
    /**
     * 提交任务
     */
    public Future submit(Runnable task){
        initThreadPoolExecutor();
        Future<?> future=mExecutor.submit(task);
        return future;
    }
    /**
     * 执行任务
     */
    public void execute(Runnable task){
        initThreadPoolExecutor();
        mExecutor.execute(task);
    }
    /**
     * 移除任务
     */
    public void remove(Runnable task){
        initThreadPoolExecutor();
        mExecutor.remove(task);
    }

}

打印的记过如下:

image.png

image.png