浅谈android应用之Thread & Process

1. 前言

更多内容请查看android生态之应用篇

直接进入主题,Thread即线程,Process即进程,经常会有人分不清楚两者,先来看官方的解释:
进程是资源分配的最小单位,线程是CPU调度的最小单位

这个回答可能比较抽象不好被理解,这边就打个最简单的比方:
在工厂中,进程就像一个车间,这个车间可以有不同的流水线,或者仅有一条流水线,这个流水线就指的是线程。线程一般职能单一,就像一条流水线的话就只生产一种产品,但是进程的话就跟车间一样,他可以包含有不同的流水线,它能产生不同种类的产品。再通俗来讲:进程就是老子,管着他众多的线程儿子。

2. Thread

2.2 线程的创建

创建Thread有两种比较常见的方式:

        new Thread(new Runnable() {
            @Override
            public void run() {
                
            }
        }).start();
        new Thread(){
            @Override
            public void run() {
                super.run();
            }
        }.start();

2.2 线程池

创建线程可以提高程序的执行效率,但是也不能无限的创建线程,这个跟系统设置有关,存在最大线程数限制。还有就是创建过多线程会导致CPU资源紧张,并且如果线程得不到释放的话,这样就会明显的感觉到程序变“卡”。重复线程创建和销毁的过程会给系统造成巨大的消耗,所以就很有必要设计一个“管理者”的存在,他的作用包括:

1.管理并复用线程、控制最大并发数等
2.实现任务线程队列缓存策略和拒绝机制
3.实现某些与时间相关的功能,如定时执行、周期执行等
4.隔离线程环境

这也就引出了线程池这一“管理者”的角色。

这边提供一个自定义线程池的模板,如果想要清楚线程池更多的细节的话,如参数含义,以及线程池种类等,这个自行百度,不再赘述:


public class BHThreadPool {
 
    ThreadPoolExecutor threadPoolExecutor;
    int corePoolSize;
    int maximumPollSize;
    long keepAliveTime;
    public static BHThreadPool instance;
 
    public static BHThreadPool getInstance() {
        if (instance == null) {
            instance = new BHThreadPool(1,1,1000);
        }
        return instance;
    }
 
    public BHThreadPool(int corePoolSize, int maximumPollSize, long keepAliveTime){
        this.corePoolSize = corePoolSize;
        this.maximumPollSize = maximumPollSize;
        this.keepAliveTime = keepAliveTime;
    }
 
    public ThreadPoolExecutor initExecutor(){
        if (threadPoolExecutor == null) {
            synchronized (BHThreadPool.class){
                TimeUnit unit =  TimeUnit.MILLISECONDS;
                ThreadFactory threadFactory = Executors.defaultThreadFactory();
                RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
                LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
 
                threadPoolExecutor = new ThreadPoolExecutor(
                        //核心线程数
                        corePoolSize,
                        //最大线程数
                        maximumPollSize,
                        //保持时间
                        keepAliveTime,
                        //保持时间对应的单位
                        unit,
                        workQueue,
                        threadFactory,
                        handler
                );
            }
        }
        return threadPoolExecutor;
    }
 
    /**
     * 执行任务
     */
    public void executeTask(Runnable runnable){
        initExecutor();
        threadPoolExecutor.execute(runnable);
    }
 
    /**
     * 提交任务
     */
    public Future<?> commitTask(Runnable runnable){
        initExecutor();
        return threadPoolExecutor.submit(runnable);
    }
 
    /**
     * 删除任务
     * removeTask()方法起作用有一个必要的前提,就是这个任务还没有开始执行,
     * 如果已经开始执行了,就停止不了该任务了,这个方法就不会起作用
     */
    public void removeTask(Runnable runnable){
        initExecutor();
        threadPoolExecutor.remove(runnable);
    }
 
    /**
     * 关闭线程池操作的方法
     */
    public void closeThread(){
        threadPoolExecutor.shutdownNow();
    }
 
    /**
     * 线程池用法
     * 1 BHThreadPool 线程池对象
     * 2 runnable
     * 3 将runnable添加到BHThreadPool线程池中去
     */
 
    //    BHThreadPool BHThreadPool = new BHThreadPool(1,1,1000);
    //    Runnable runnable = new Runnable() {
    //        @Override
    //        public void run() {
    //    可执行发动handler操作
    //            Log.e("log", "子线程操作");
    //        }
    //    };
    //
    //    BHThreadPool.executeTask(runnable);
 
}

2.3 线程之间的交流

这边提它一下这个线程之间的交流,这个问题开发的时候会比较常见。我们可能在处理网络数据或者其他耗时操作的逻辑的时候,通常会独自开一个线程进行处理,然后当线程完成之后再告诉UI线程进行UI更新操作,这个就需要用到Handler这个线程交流的使者。

这边也只提一下如何使用handler,如果想要了解handler的更多细节的话,可以自行百度,或者看之前我写的有关handler的文章:浅谈android应用之消息机制

使用handler的常见有两种方式:

一,采用sendEmptyMessageDelayed

package com.awaitu.easymusic.view;

import android.os.Bundle;

import com.awaitu.easymusic.R;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.Window;

public class SplashActivity extends Activity {

    private static final int SPLASH_TIME = 3000;
    @SuppressLint("HandlerLeak") private Handler splashHandler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1)
            {
                SplashActivity.this.stopSplash();
                this.removeMessages(1);
            }
        }
    };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_splash);
        splashHandler.sendEmptyMessageDelayed(1, SplashActivity.SPLASH_TIME);
    }

    private void stopSplash()
    {
        Intent intent = new Intent(SplashActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            splashHandler.sendEmptyMessage(1);
            return true;
        }
        return super.onTouchEvent(event);
    }

}

二,采用postdelay

package com.awaitu.easymusic.view;

import android.os.Bundle;

import com.awaitu.easymusic.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.Window;

public class SplashActivity extends Activity {

    private static final int SPLASH_TIME = 3000;
    Handler mhandler;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_splash);
        mhandler = new Handler();
        mhandler.postDelayed(new SplashHandler(),SPLASH_TIME);
    }
    private class SplashHandler implements Runnable{
        public void run(){
            startActivity(new Intent(getApplication(),MainActivity.class));
            finish();
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            mhandler.post(new SplashHandler());

            return true;
        }
        return super.onTouchEvent(event);
    }

}

3. Process

3.1 进程的创建

在android系统中,一个应用程序实质就是一个进程,他的启动是由虚拟机fork出来的,原理跟linux创建进程的过程类似。

3.3 IPC方式

这里的内容直接看我这篇文章就差不多了:浅谈android应用之IPC

发布了70 篇原创文章 · 获赞 24 · 访问量 8271

猜你喜欢

转载自blog.csdn.net/angelsmiling/article/details/102810813