广告
返回顶部
首页 > 资讯 > 移动开发 >分析Android中线程和线程池
  • 660
分享到

分析Android中线程和线程池

2024-04-02 19:04:59 660人浏览 薄情痞子
摘要

目录前言HandlerThreadIntentService线程池的好处ThreadPoolExecutor线程池的分类FixedThreadPoolCachedThreadPool

前言

由于内容过多,所以将分为上下两部分,第一部分主要和大家谈谈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 Service。Intent 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中Executor,Executor是一个空的接口,真正的线程池实现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>()));

    }

以上就是分析Android中线程和线程池的详细内容,更多关于Android中线程和线程池的资料请关注编程网其它相关文章!

--结束END--

本文标题: 分析Android中线程和线程池

本文链接: https://www.lsjlt.com/news/127782.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 分析Android中线程和线程池
    目录前言HandlerThreadIntentService线程池的好处ThreadPoolExecutor线程池的分类FixedThreadPoolCachedThreadPool...
    99+
    2022-11-12
  • Android中线程池
    一、线程池的优点 说到线程池的优点就要先说一下不用线程池的坏处 在早些年开发都是直接new Thread()直接创建线程,倘若有N个异步就要创建N个线程,这会导致线程的频繁创建和销毁线程不可控,每个线程都各自执行,内存资源竞争激烈,这可能会...
    99+
    2023-09-17
    android java
  • Android中的线程和线程池有什么作用
    今天小编给大家分享一下Android中的线程和线程池有什么作用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言从用途上来说...
    99+
    2023-07-04
  • Android Dispatchers.IO线程池深入刨析
    目录一. Dispatchers.IO1.Dispatchers.IO2.DefaultScheduler类3.LimitingDispatcher类4.ExperimentalCo...
    99+
    2022-11-13
  • Java中线程池的示例分析
    小编给大家分享一下Java中线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java线程池线程的缺点:线程的创建它会开辟本地方法栈、JVM栈、程序计...
    99+
    2023-06-20
  • Android开发中线程池源码解析
    线程池(英语:thread pool):一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了...
    99+
    2022-11-12
  • 浅谈Android 的线程和线程池的使用
    Android 的线程和线程池从用途上分,线程分为主线程和子线程;主线程主要处理和界面相关的事情,子线程则往往用于耗时操作。主线程和子线程主线程是指进程所拥有的线程。Android 中主线程交 UI 线程,主要作用是运行四大组件以及处理它们...
    99+
    2023-05-30
    android 线程池 roi
  • 一文彻底了解Android中的线程和线程池
    目录前言1.主线程和子线程2.Android中的线程形态2.1 AsyncTask2.2 AsyncTask的工作原理2.3 HandleThread2.4 IntentServic...
    99+
    2022-12-20
    Android 线程池 android线程机制 线程和线程池
  • Python中线程池模块之多线程的示例分析
    这篇文章将为大家详细讲解有关Python中线程池模块之多线程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、线程池模块引入from concurrent.futures i...
    99+
    2023-06-15
  • Android的线程、多线程和线程池面试题有哪些
    这篇“Android的线程、多线程和线程池面试题有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android的线程、多...
    99+
    2023-06-04
  • spring task和线程池的示例分析
    小编给大家分享一下spring task和线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!spring task和线程池的研究1、如何实现...
    99+
    2023-06-22
  • Java线程池的示例分析
    小编给大家分享一下Java线程池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么需要线程池我们知道创建线程的常用方式就是 new Thread() ...
    99+
    2023-06-22
  • android中UI主线程与子线程深入分析
    本文较为深入的分析了android中UI主线程与子线程。分享给大家供大家参考。具体如下: 在一个Android 程序开始运行的时候,会单独启动一个Process。默认的情况下,...
    99+
    2022-06-06
    线程 Android
  • Java线程池的分析和使用详解
    目录1.   引言2.线程池的使用线程池的创建线程池的关闭3.   线程池的分析4.   合...
    99+
    2022-11-12
  • SpringBoot线程池和Java线程池的使用和实现原理解析
    目录SpringBoot线程池和Java线程池的用法和实现原理使用默认的线程池方式一:通过@Async注解调用方式二:直接注入 ThreadPoolTaskExecutor...
    99+
    2023-05-15
    SpringBoot线程池和Java线程池用法 SpringBoot线程池
  • Android 开发中线程的分析
    Android 开发中线程的分析 今天早上把公司给的任务做完了之后,突然就有点无聊,于是,把以前学的那些东西翻了翻,博客看了看,就看到一个关于线程的博客,有了很大的争议,我也差...
    99+
    2022-06-06
    线程 Android
  • Android线程池是什么
    本篇内容主要讲解“Android线程池是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android线程池是什么”吧!我们都知道线程池的用法,一般就是先new一个ThreadPoolExec...
    99+
    2023-06-22
  • SpringBoot线程池和Java线程池怎么使用
    这篇文章主要介绍“SpringBoot线程池和Java线程池怎么使用”,在日常操作中,相信很多人在SpringBoot线程池和Java线程池怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringB...
    99+
    2023-07-06
  • Java 阻塞队列和线程池原理分析
    目录【1】阻塞队列一、什么是阻塞队列?二、阻塞队列有什么用?三、阻塞队列的简单实用【2】Java 线程池一、我们为什么需要Java 线程池?使用它的好处是什么?二、Java中主要提供...
    99+
    2022-11-12
  • 详解Java线程池和Executor原理的分析
    详解Java线程池和Executor原理的分析线程池作用与基本知识在开始之前,我们先来讨论下“线程池”这个概念。“线程池”,顾名思义就是一个线程缓存。它是一个或者多个线程的集合,用户可以把需要执行的任务简单地扔给线程池,而不用过多的纠结与执...
    99+
    2023-05-31
    java 线程池 executor
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作