Android常用多线程

ThreadPoolExecutor

CachedThreadPool
只有非核心线程,且总线程数量不固定,当任务到来时,有空闲线程,就立即交由该线程去处理任务,否则就立即创建新线程去处理该任务,保证第一时间执行任务。但空闲线程有超时机制,空闲超过60秒,就会被系统回收。适合执行量大耗时少的任务。
FixThreadPool
只有核心线程,并且数量固定的,也不会被回收。当所有线程都活动时,因为队列没有限制大小,新任务会等待执行。由于线程不会回收,FixThreadPool会更快地响应外界请求。
SingleThreadPool
只有一个核心线程,能够确保所有任务都在同一线程中按顺序完成。因此不需要处理线程同步的问题。
ScheduledThreadPool
拥有固定数量核心线程数量和不固定的非核心线程数量的线程池,4个里面唯一一个有延迟执行和周期重复执行的线程池。

使用方式(以newCachedThreadPool举例)

ExecutorService executo = Executors.newCachedThreadPool();
executor1.execute(new Runnable() {
    @Override
    public void run() {
    ......
    }
});

AsyncTask

// 1.doInBackground方法中参数的类型
// 2.onProgressUpdate方法参数的类型
// 3.doInBackground方法的返回值类型,也是onPostExecute方法的参数的类型
class LoadDataAsyncTask extends AsyncTask<String, Integer, List<Integer>>{

    // 运行在UI线程,且在doInBackground方法运行前执行
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    // 在子线程中执行,且方法的执行结果会作为参数传入onPostExecute方法中
    @Override
    protected List<Integer> doInBackground(String... strings) {
        List<Integer> a = new ArrayList<>();

        return a;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    // 运行在UI线程,且在doInBackground方法运行结束后执行
    @Override
    protected void onPostExecute(List<Integer> list) {
        super.onPostExecute(list);
    }
}

调用方式

LoadDataAsyncTask task = new LoadDataAsyncTask();
String param = "qqqq";
// 这个方法通常和THREAD_POOL_EXECUTOR一起使用,允许多个任务在线程池中异步并发执行
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, param);
// execute方法实际内部调用的是executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params)
// 把多个线程按串行的方式执行,所以是同步执行的,也就是说,只有当一个线程执行完毕之后,才会执行下个线程。
task.execute(param);

Handler

Handler是一套 Android 消息传递机制 / 异步通信机制。

  • 为什么要用 Handler消息传递机制
    答:多个线程并发更新UI的同时 保证线程安全。

背景:在Android开发中为了UI操作是线程安全的,规定只允许UI线程里操作UI组件。
冲突:在实际操作开发中,存在多个线程并发操作UI组件的情况,因而会导致UI操作的线程不安全。
需求:因为上面的冲突产生新的需求,多个线程既可以并发操作UI组件,又能保证线程安全。
解决方案:Handler消息传递机制,即工作线程需要通知UI时,全部通过Handler通知主线程,从而在主线程操作UI。
所以,Handler就是在多线程的应用场景中,将工作线程中需更新UI的操作信息传递到UI主线程,使得主线程可根据工作线程的需求更新UI,从而实现工作线程对UI的更新处理,并避免线程操作不安全的问题,最终实现异步消息的处理。

使用方式
1、在主线程中创建Handler实例。
2、通过两种方式通知UI线程:Handler.sendMessage()、Handler.post()。这两种方式实质都是通过调用sendMessageDelayed(@NonNull Message msg, long delayMillis)来实现的。

sendMessage方式

Handler handler = new Handler(Looper.myLooper()) {
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case 111:
        }
    }
};
Message message = new Message();
message.what = 111;
message.obj = new Date();
handler.sendMessage(message);

post方式

Handler handler = new Handler(Looper.myLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
    }
});

Handler还可以用来延迟执行任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值