线程池的工作原理及使用示例

转载地址:https://www.cnblogs.com/nullzx/p/5175574.html

1. 为什么要使用线程池?

 我们现在考虑最简单的服务器工作模型:服务器每当接收到一个客户端请求时就创建一个线程为其服务。这种模式理论上可以工作的很好,但实际上会存在一些缺陷,服务器应用程序中经常出现的情况是单个客户端请求处理的任务很简单但客户端的数目却是巨大的,因此服务器在创建和销毁线程所花费的时间和系统资源可能比处理客户端请求处理的任务花费的时间和资源更多。

线程池技术就是为了解决上述问题而出现的。合理的使用线程池便可重复利用已创建的线程,以减少在创建线程和销毁线程上花费的时间和资源。除此之外,线程池在某些情况下还能动态的调整工作线程的数量,以平衡资源消耗和工作效率。同时线程池还提供了对池中工作线程进行统一的管理的相关方法。

2. 线程池的简要工作模型

线程池的工作原理及使用示例_第1张图片

组成:运行Runnable的Thread对象,另一部分就是阻塞队列

由线程池创建的Thread对象其内部的run方法会通过阻塞队列的take方法获取一个Runnable对象,然后执行这个Runnable对象的run方法。当Runnable对象的run方法执行完毕以后,Thread中的run方法又循环的从阻塞队列中获取下一个Runnable对象继续执行。这样就实现了Thread对象的重复利用,也就减少了创建线程和销毁线程所消耗的资源。当需要向线程池提交任务时会调用阻塞队列的offer方法向队列的尾部添加任务。提交的任务实际上就是是Runnable对象或Callable对象。


3. Executor、ExecutorService、AbstractExecutorService、ThreadPoolExecutor、Executors之间的关系

线程池的工作原理及使用示例_第2张图片

submit相关方法:向线程池添加执行的任务

shutdown方法:此方法执行后不得向线程池再提交任务,如果有空闲线程则销毁空闲线程,等待所有正在执行的任务及位于阻塞队列中的任务执行结束,然后销毁所有线程。

shutdownNow方法:此方法执行后不得向线程池再提交任务,如果有空闲线程则销毁空闲线程,取消所有位于阻塞队列中的任务,并将其放入List容器,作为返回值。取消正在执行的线程(实际上仅仅是设置正在执行线程的中断标志位)。

invokeAll方法:一次性向线程池提交多个任务,并返回全部结果。

invokeAny方法:一次性向线程池提交多个任务,并将第一个得到的结果作为返回值,然后立刻取消所有正在执行的线程。

isTerminated方法:池中的线程全部销毁后,该方法返回真,否则返回假。


5. 线程池使用示例


package com.peace.pms.Test;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * @Author: cxx
 * @Date: 2018/3/3 17:16
 */
public class ThreadPoolDemo {
    public static class Taskdemo implements Runnable{
        private String id;
        Taskdemo(String id){
            this.id=id;
        }
        @Override
        public void run() {
            System.out.println("Thread "+id+" is working");
            try {
                //每个任务随机延时1s以内的时间以模拟线程的运行
                Thread.sleep(new Random().nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread "+id+" over");
        }
    }
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);//线程池中,3工作线程
        threadPool.execute(new Taskdemo("a"));
        threadPool.execute(new Taskdemo("b"));
        threadPool.execute(new Taskdemo("c"));
        threadPool.execute(new Taskdemo("d"));
        threadPool.execute(new Taskdemo("e"));
        threadPool.shutdown();
        while(!threadPool.isTerminated()){
        }
        System.out.println("Thread Pool is over");
    }
}
线程池的工作原理及使用示例_第3张图片

你可能感兴趣的:(核心Java)