Android对线程池的正确理解

线程池

new Thread()缺点
每次新建对象 性能差
线程缺乏同意管理 可能占用过多资源导致OOM
缺乏功能 如定时执行、中断线程

线程池的优点在于
重用存在的线程,减少对象、消亡的开销,性能好
有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多的资源竞争,避免堵塞
提供定时执行、定期执行、单线程、并发数控制等功能

Java线程池
Java通过Executors提供四种线程池,分别为:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

// CachedThreadPool只有非核心线程 最大线程数非常大 所有线程都活动时 会为新任务创建新线程
// 否则利用空闲线程(60s空闲时间 过了就会被回收 所以线程池中有0个线程的可能)处理任务
// 比较适合执行大量的耗时较少的任务
ExecutorService threadPool = Executors.newCachedThreadPool();
// 核心线程数固定 非核心线程(空闲会被立即回收)数没有限制
// ScheduledThreadPool主要用于执行定时任务以及有固定周期的重复任务
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
threadPool.scheduleAtFixedRate(runnable
        , 1000 // 首次执行延迟时间
        , 2000 // 执行间隔时间
        , TimeUnit.MILLISECONDS); // 秒或者毫秒
// SingleThreadPool只有一个核心线程
// 确保所有任务都在同一线程中按顺序完成 因此不需要处理线程同步的问题
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// FixThreadPool只有核心线程 并且数量固定的
// 不会被回收 所有线程都活动时 因为队列没有限制大小 新任务会等待执行
ExecutorService threadPool = Executors.newFixedThreadPool(5);

将线程添加到线程池的方式

//通过这种方式将线程任务加载到线程池当中
threadPool.execute(runnable);
// 这种方式与第一种的区别在于可以使用一个Future对象来判断当前的线程是否执行完毕
// 但是这种方法只能判断当前的线程是否执行完毕,无法返回数据信息
// 通过 future.get() 的结果是否为null来判断线程是否执行完毕
Future future = threadPool.submit(runnable);
// 这种方式与前一种不同 传递的参数为Callable对象 Callable与Runnbale很相似
// 但是Callable的call()方法可以返回数据信息
// 通过Future就能够获取到其中的信息 而Runnbale.run()方法时无法获取数据信息的
// 通过 future.get() 的结果来获取 call()方法返回的数据
future = threadPool.submit(new Callable() {
    public Object call() throws Exception {
        return "Result";
    }
});
Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 1";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 2";
    }
});
callables.add(new Callable<String>() {
    public String call() throws Exception {
        return "Task 3";
    }
});
// invokeAny() 接收一个包含 Callable 对象的集合作为参数
// 调用该方法不会返回 Future 对象,而是返回集合中某一个 Callable 对象的结果
// 而且无法保证调用之后返回的结果是哪一个Callable
// 只知道它是这些 Callable 中一个执行结束的 Callable 对象
// 这里执行后的结果是随机的...也就是输出是不固定的
//
try {
    String result = threadPool.invokeAny(callables);
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    e.printStackTrace();
}
// inVokeAll()这个方法和上面不同的地方就在于它可以返回所有Callable的执行结果// 获取到所有的执行结果,我们可以对其进行管理try {    List<Future<String>> futures = threadPool.invokeAll(callables);} catch (InterruptedException e) {    e.printStackTrace();}

停止线程的方法

// shutdown并不是直接关闭线程池 而是不再接受新的任务
// 如果线程池内有任务 那么把这些任务执行完毕后 关闭线程池
threadPool.shutdown();

// 这个方法表示不再接受新的任务 并把任务队列中的任务直接移出掉
// 如果有正在执行的 尝试进行停止
threadPool.shutdownNow();

猜你喜欢

转载自blog.csdn.net/qq_36437339/article/details/80859939