线程知识点总结

知识是什么,知识就是看完了书把书扔掉之后脑中那些清晰、准确、必要的概念。

之前也写了挺多关于线程的博客,但是由于自己基础不扎实,大多数都是摘录别人的东西。所以这篇文章就是对一些重要的概念进行总结,把知识归纳整理,这篇博客会长期更新,只要遇到了一些自己不懂而且重要的理论就会添加上去。

进程优先级的5种类型:

前台进程、可见进程、服务进程、后台进程、空进程

1、前台进程 (Foreground process)

一个正在与用户交互的Activity

进程持有一个Service,这个Service处于这几种状态:
①Service与用户正在交互的Activity绑定。
②Service是在前台运行的,即它调用了 startForeground()。
③Service正在执行它的生命周期回调函数(onCreate(), onStart(), or onDestroy())。

进程持有一个BroadcastReceiver,这个BroadcastReceiver正在执行它的 onReceive() 方法。

2、可见进程(Visible process)

进程持有一个Activity,这个Activity不在前台,但是仍然被用户可见(处于onPause()调用后又没有调用onStop()的状态,比如,前台的activity打开了一个对话框,这样activity就会在其后可见)。

进程持有一个Service,这个Service和一个可见的(或者前台的)Activity绑定。

3、服务进程 (Service process)

  如果一个进程中运行着一个service,这个service是通过 startService() 开启的,并且不属于上面两种较高优先级的情况,这个进程就是一个服务进程。

在Service中新启动线程
上传一个图片文件,应该开启一个service来进行上传工作,这样在用户离开activity时工作仍在进行

4、后台进程 (Background process)

进程持有一个用户不可见的activity(activity的onStop()被调用,但是onDestroy()没有调用的状态),就认为进程是一个后台进程。

后台播放音乐,后台下载数据等

直接在Activity中新开一条线程来做耗时操作,当该Activity退出到桌面或其他情况

5、空进程

一个进程不包含任何活跃的应用组件

一个进程当中已经没有数据在运行了,但是内存当中还为这个应用驻留了一个进程空间

如何提高Service优先级

1、设置属性priority最高优先级,1000是最高值

2、在onStartCommand里面调用 startForeground()方法把Service提升为前台进程级别

3、onStartCommand方法,返回START_STICKY

public int onStartCommand(Intent intent, int flags, int startId) {

flags = START_STICKY;
returnsuper.onStartCommand(intent, flags, startId);
}

4、在onDestroy方法里发广播重启service

5、监听系统广播判断Service状态

6、将该进程设置为常驻内存进程:在AndroidManifest的Application中添加android:persistent=”true”

开启子线程的方式

Thread、AsyncTask、HandlerThread、IntentService、ThreadExecutor

1、Thread

简单地开启一个子线程进行处理,比如说处理一张图片,读取资源文件,读写数据库等。
要手动控制开启和结束,不然会一直运行在后台,即使程序退出

2、AsyncTask

适合与界面进行频繁交互,比如说进度条,也可以做Thread可以做的事

3、HandlerThread

适合处理在前台的多线程串行的程序

4、IntentService

适合处理在后台运行的,多线程串行程序

5、ThreadExecutor

适合反复多次使用线程的程序,比如说音乐下载,图片加载(ImageLoader)

Thread

1、子线程创建Handler

new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler(Looper.myLooper()) {
                    @Override
                    public void handleMessage(Message msg) {
                        mTextView.setText("改变文字");
                    }
                };
                Looper.loop();
                handler.sendEmptyMessage(123);

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

AsyncTask

1、执行并发操作代码:

loadImageAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, path);

HandlerThread

IntentService

ThreadExecutor

execute和submit的区别
  • submit内部调用execute

  • submit有返回值

  • submit方便exception处理

Callable和Runnable的区别
  • Callable中的call()方法类似Runnable的run()方法,就是前者有返回值,后者没有。

  • 两者都是为那些实例可能被另一个线程执行的类设计的。

  • 但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

预设的线程池
  1. newFixedThreadPool 固定数量

  2. newSingleThreadExecutor 串行

  3. newCachedThreadPool 无限大

  4. newScheduledThreadPool 固定数量,周期性执行

BlockingQueue等待队列
  1. ArrayBlockingQueue:数组结构的阻塞队列

  2. LinkedBlockingQueue:链表结构的阻塞队列

  3. PriorityBlockingQueue:有优先级的阻塞队列

  4. SynchronousQueue:不会存储元素的阻塞队列

饱和策略

AbortPolicy : 默认的实现,直接抛出一个RejectedExecutionException异常,让调用者自己处理。

DiscardPolicy : 如果队列满了,后续的任务都抛弃掉。

DiscardOldestPolicy : 将等待队列里最旧的任务踢走,让新任务得以执行。

CallerRunsPolicy : 既不抛弃新任务,也不抛弃旧任务,而是直接在当前线程运行这个任务。

ThreadFactory

每当线程池需要创建一个新线程,都是通过线程工厂获取。如果不为ThreadPoolExecutor设定一个线程工厂,就会使用默认的defaultThreadFactory

平时打印线程池里线程的name时,会输出形如pool-1-thread-1之类的名称,就是在这里设置的。这个默认的线程工厂,创建的线程是普通的非守护线程,如果需要定制,实现ThreadFactory后传给ThreadPoolExecutor即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值