纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Android中线程和线程池 分析Android中线程和线程池

handsome黄   2021-06-08 我要评论
想了解分析Android中线程和线程池的相关内容吗handsome黄在本文为您仔细讲解Android中线程和线程池的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Android,线程,Android,线程池下面大家一起来学习吧

前言

由于内容过多所以将分为上下两部分第一部分主要和大家谈谈Android中的线程以及在Android中的常用的线程池第二部分我们一起来了解一下AsyncTask的使用和工作原理

HandlerThread

HandlerThread是Thread的子类它是一种可以使用Handler的Thread,它的实现比较简单我们来看看它的源码:

package android.os;

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }


      public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }


       protected void onLooperPrepared() {
    }



    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }



     public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }

        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }



       public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }





      public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }




     public int getThreadId() {
        return mTid;
    }
}

为了让大家看清楚我们源码的一些英文注释干掉了现在就很清晰了整个类中除了构造方法和对外提供几个public方法以外就剩一个方法了run()从它的实现来看和普通的Thread实现没有什么区别都是在run()方法中执行耗时操作不过HandlerThread内部创建了消息队列并且run()方法是一个无限循环的方法当我们不需要HandlerThread的时候我们可以调用quitSafely()或者quit()方法来结束这个线程这是比较方便的

IntentService

IntentService是一种特殊的Service它是Service的子类并且它是一个抽象类所以必须创建它的子类才可以使用Intent ServiceIntent Service可用于执行后台的耗时任务当任务执行完毕它会自己结束不需要开发着手动结束它这里需要注意一个问题Intentservice内置有线程但是它还是属于Service所以它的优先级会比线程高很多所以不容易被系统杀死所以比较合适去执行一些优先级比较高的任务看看它的源码:

package android.app;

import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;



public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;



    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }



        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }




    public IntentService(String name) {
        super();
        mName = name;
    }




   public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }




    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }




      @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }




    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }




    public IBinder onBind(Intent intent) {
        return null;
    }




    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

这里就很简单了这些方法对于经常使用Service的朋友来说就很熟悉了大家看onCreate()方法没错IntentService就是封装了HandlerThread和Handler

当我们启动IntentService是onCreate(),方法将会被调用然后就会创建HandlerThread和ServiceHandler而onStartCommand()方法又调用了onStart()方法从onStart()方法可以看出IntentService 仅仅是通过ServiceHandler来发一个消息这个消息会在HandlerThread中被处理掉

大家看这个onStart()方法将intent作为消息传递给onHandleIntent这个intent通常是我们传递进来的数据而onHandleIntent就是通过这个intent来区别具体的后台任务的

好了AsyncTask的使用和工作原理我们会在下一章在说下面我们看看线程池吧

不知道大家有没有遇到过这种情况我们在写项目遇到耗时操作的时候怎么办呢是不是new Thread().start那这样的话整个项目中得new多少个Thread这种明显是很浪费性能毕竟线程也是好资源的嘛那么有没有一种可以方法对线程进行复用呢?答案就是线程池

线程池的好处

1、重用线程池中的线程避免因为线程的创建和销毁带来的性能开销

2、能有效的控制线程池中的线程并发数避免大量线程之间因为互相抢占资源而导致的阻塞现象

3、能够对线程进行简单的管理并提供定时执行以及指定间隔循环执行等功能

ThreadPoolExecutor

Android中的线程池概念是来源于java中ExecutorExecutor是一个空的接口真正的线程池实现ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

简单介绍一下ThreadPoolExcutor各个参数的含义

corePoolSize:线程池的核心线程数默认情况下核心线程会在线程池中一直存活即使他们处于闲置状态当我们把ThreadPoolExecutor中的allowCoreThreadTimeOut属性设置为true那么闲置的核心线程在等待新任务的时候如果时间超过keepAliveTime所设置的时间核心线程将会被回收

maximumPoolSize:设置最大线程池能够容纳的最大线程数当线程池中的线程达到这个数以后新任务将会被阻塞

keepAliveTime:非核心线程数闲置的时间

unit:指定keepAliveTime参数的时间单位

workQueue:线程池中的任务队列

threadFactory:线程工厂为线程池提供创建新线程的功能

线程池的分类

Android中常见的线程池有四种FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor

FixedThreadPool

FixedThreadPool线程池是通过Executors的new FixedThreadPool方法来创建它的特点是该线程池中的线程数量是固定的即使线程处于闲置的状态它们也不会被回收除非线程池被关闭当所有的线程都处于活跃状态的时候新任务就处于队列中等待线程来处理注意FixedThreadPool只有核心线程没有非核心线程

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                            0L, TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory);
}

CachedThreadPool

CachedThreadPool线程池是通过Executors的newCachedThreadPool进行创建的它是一种线程数目不固定的线程池它没有核心线程只有非核心线程当线程池中的线程都处于活跃状态就会创建新的线程来处理新的任务否则就会利用闲置的线程来处理新的任务线程池中的线程都有超时机制这个超时机制时长是60s超过这个时间闲置的线程就会被回收这种线程池适合处理大量并且耗时较少的任务这里得说一下CachedThreadPool的任务队列基本都是空的

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                60L, TimeUnit.SECONDS,
                                new SynchronousQueue<Runnable>());
}

ScheduledThreadPool

ScheduledThreadPool线程池是通过Executors的newScheduledThreadPool进行创建的它的核心线程是固定的但是非核心线程数是不固定的并且当非核心线程一处于空闲状态就立即被回收这种线程适合执行定时任务和具有固定周期的重复任务

public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }


public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

SingleThreadExecutor

SingleThreadExecutor线程池是通过Executors的newSingleThreadExecutor方法来创建的这类线程池中只有一个核心线程也没有非核心线程这就确保了所有任务能够在同一个线程并且按照顺序来执行这样就不需要考虑线程同步的问题

public static ExecutorService newSingleThreadExecutor() {

        return new FinalizableDelegatedExecutorService

            (new ThreadPoolExecutor(1, 1,

                                    0L, TimeUnit.MILLISECONDS,

                                    new LinkedBlockingQueue<Runnable>()));

    }

相关文章

猜您喜欢

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式