一、线程
线程的作用:在后台执行耗时操作,使用户不必等待。
java线程:

1
2
3
4
5
6
new Thread(){
@Override
public void run() {
super.run(); //执行操作
}
}.start();

二、线程池
系统创建一个线程,执行完成后销毁,频繁创建销毁线程就会大大降低系统的效率
同时限制线程数目,防止因为消耗过多的内存,而把系统累趴下,就需要用到线程池

  1. 创建一个能容纳10个线程的线程池

    1
    private ExecutorService executorService = Executors.newFixedThreadPool(10); //线程缓存池
  2. 将线程提交到线程池执行:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    executorService.execute(new Runnable() {
    @Override
    public void run() {
    }
    });

Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。

比较重要的几个类:

说明
ExecutorService 真正的线程池接口。
ScheduledExecutorService 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。
ThreadPoolExecutor ExecutorService的默认实现。
ScheduledThreadPoolExecutor 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。
  1. newSingleThreadExecutor
    创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

  2. newFixedThreadPool
    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

  3. newCachedThreadPool
    创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

  4. newScheduledThreadPool
    创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

三、 android中线程使用
在android端Thread线程里是不能直接执行修改界面的的操作的。界面的修改只能在主线程中执行,保证线程安全问题。

那么在Thread怎么修改界面呢?

  1. 可以创建一个Handler,实现里面的handleMessage方法,在handleMessage中可执行修改界面操作

    1
    2
    3
    4
    5
    6
    7
    Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    }
    };

    然后在Thread线程发送消息,Handler会处理消息调用handleMessage方法:

    1
    handler.sendEmptyMessage(0);
  2. 另外一种方法,调用Activity的runOnUiThread方法或者View的post方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    executorService.execute(new Runnable() {
    @Override
    public void run() {
    History history = new History();
    history.content = search_et.getText().toString();
    history.creteTime = DateUtil.getStr(new Date(), DateUtil.yMdHms);
    history.type = type;
    HistoryDao.save(context, history);
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    //执行UI界面操作
    }
    });
    }
    });
  3. android对Thread+Handler有一个类可替代:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class MyTask extends AsyncTask{
    @Override
    protected void onPreExecute() {
    super.onPreExecute();
    //在主线程执行,在doInBackground前执行,可弹出等待Dialog
    }
    @Override
    protected Object doInBackground(Object[] params) {
    //子线程,执行耗时操作
    return null;
    }
    @Override
    protected void onPostExecute(Object o) {
    super.onPostExecute(o);
    //最后执行,主线程中执行,可执行UI界面操作,关闭Dialog
    }
    }
    new MyTask().execute();

    Task在API 11及以上串行执行,需要并行执行则需要调用如下:

    1
    new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
文章目录