线程池的处理流程:
线程池的处理流程:
线程池执行示意图:
1,首先线程池判断基本线程池是否已满(< corePoolSize ?)?没满,创建一个工作线程来执行任务。满了,则进入下个流程。
2,其次线程池判断工作队列是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程。
3,最后线程池判断整个线程池是否已满(< maximumPoolSize ?)?没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务。
总结:线程池优先要创建出基本线程池大小(corePoolSize)的线程数量,没有达到这个数量时,每次提交新任务都会直接创建一个新线程,当达到了基本线程数量后,又有新任务到达,优先放入等待队列,如果队列满了,才去创建新的线程(不能超过线程池的最大数maxmumPoolSize)
向线程池提交任务的两种方式:
1)通过execute()方法
- ExecutorService threadpool= Executors.newFixedThreadPool(10);
- threadpool.execute(new Runnable(){...});
这种方式提交没有返回值,也就不能判断任务是否被线程池执行成功。
2)通过submit()方法
- Future<?> future = threadpool.submit(new Runnable(){...});
- try {
- Object res = future.get();//获取任务执行结果
- } catch (InterruptedException e) {
- // 处理中断异常
- e.printStackTrace();
- } catch (ExecutionException e) {
- // 处理无法执行任务异常
- e.printStackTrace();
- }finally{
- // 关闭线程池
- executor.shutdown();
- }
使用submit 方法来提交任务,它会返回一个Future对象,通过future的get方法来获取返回值,get方法会阻塞住直到任务完成,而使用get(long timeout, TimeUnit unit)方法则会阻塞一段时间后立即返回,这时有可能任务没有执行完。