方法我们通过继承Thread类和实现runnable接口或者callable接口三种方式实现。

继承Thread类实际上也是实现了runnable接口,被继承的类主要是实现run()方法,通过start()方法调用。

而callable接口是属于Executor

对比与Runnable接口功能的区别是:
(1).Callable可以在任务结束后提供一个返回值,Runnable没有这个功能
(2).Callable中的call()方法可以抛出异常,而Runnable的run()方法不能抛出异常
(3).运行Callable可以拿到一个Future对象,Future独享表示异步计算的结果,它提供了检查计算是否完成的方法。由于线程属于异步计算模型,因此无法从别的线程中得到函数
的返回值,在这种情况下,就可以使用Future来监视目标线程调用call()方法的情况,放调用Future的get()方法以获取结果时,当前线程就会阻塞,知道call()方法结束返回结果。 我们可以使用多线程来达到最优效率,但是,线程不是越多就越好,线程过多,创建和销毁就会消耗系统的资源,也不方便管理。

除此之外,多线程还会造成并发问题,线程并发数量过多,抢占系统资源从而导致阻塞。

我们将线程放入线程池,由线程池对线程进行管理,可以对线程池中缓冲的线程进行复用,这样,就不会经常去创建和销毁线程了,从而省下了系统的资源。

线程池能够有效的控制线程并发的数量,能够解决多线程造成的并发问题。

ThreadPoolExecutor

Java提供了ThreadPoolExecutor线程池类,他的构造方法有四个,主要是参数不同

corePoolSize为的线程池最大核心线程数量

maximumPoolSize为最大线程池数量

keepAliveTime 当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间

unit 存活时间的单位

workQueue 存放线程的工作队列

handler:超出线程范围和队列容量的任务的处理程序(拒绝策略)

当线程放入线程池中,当线程的数量已经等于最大的核心线程数量,此线程就会放入线程队列当中,等待线程的调用。

线程池的最大线程数(线程总数,maximumPoolSize)= 核心线程数(corePoolSize)+非核心线程数

核心线程是永远不会被线程池丢弃回收(即使核心线程没有工作),非核心线程则是超过一定时间(keepAliverTime)则就会被丢弃

Excutors工具类

java提供了Excutors工具类,适用于一下小项目,对于一些大型程序还是需要自己创建ThreadPoolExecutor类,因为Excutors可能会造成OOM(堆内存溢出)

FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。
CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。
方法 说明
newFixedThreadPool(int nThreads) 创建固定大小的线程池
newSingleThreadExecutor() 创建只有一个线程的线程池
newCachedThreadPool() 创建一个不限线程数上限的线程池,任何提交的任务都将立即执行
newScheduledThreadPool(int nThreads) 创建一个支持定时、周期性或延时任务的限定线程数目的线程池
newSingleThreadScheduledExecutor() 创建一个支持定时、周期性或延时任务的单个线程的线程池

线程池获取执行结果

把线程提交给线程池中,有两种方法,一种是submit,另外一种则是execute

execute没有返回值,性能会好很多,submit返回一个Future对象,如果想知道线程结果就使用submit提交,而且它能在主线程中通过Future的get方法捕获线程中的异常。

这两种方法的参数必须要实现runnable接口或者是callable对象

线程池的处理结果、以及处理过程中的异常都被包装到Future中,并在调用Future.get()方法时获取,执行过程中的异常会被包装成ExecutionException。

关闭线程池

可以通过shutdown()或者shutdownNow()方法

shutdown() :   不再接受新的任务,之前提交的任务等执行结束再关闭线程池

shutdownNow() :不再接受新的任务,试图停止池中的任务再关闭线程池,返回所有未处理的线程list列表。

Semaphore 的使用方式

Semaphore 是 synchronized 的加强版,作用是控制线程的并发数量。(并发控制信号量)

我们可以在主要执行任务的call()方法或者run()方法中使用semaphore来控制并发。

semaphore的构造方法有两个

第一个构造方法的参数为同一时刻允许线程进入的个数,如果为1,就相当于单个线程。

第二个构造方法的参数为线程公平性isFair

 isFair 的意思就是,是否公平,获得锁的顺序与线程启动顺序有关,就是公平,先启动的线程,先获得锁。isFair 不能100% 保证公平,只能是大概率公平。

 isFair 为 true,则表示公平,先启动的线程先获得锁。

在 semaphore.acquire() 和 semaphore.release()之间的代码,同一时刻只允许制定个数的线程进入, 因为semaphore的构造方法是1,则同一时刻只允许一个线程进入,其他线程只能等待。

acquire:

线程池ThreadPoolExecutor的使用方法的更多相关文章

  1. [3]java1.8线程池—ThreadPoolExecutor

    Wiki 上是这样解释的:Thread Pool 作用:利用线程池可以大大减少在创建和销毁线程上所花的时间以及系统资源的开销! 下面主要讲下线程池中最重要的一个类 ThreadPoolExecutor ...

  2. 线程池ThreadPoolExecutor的学习

    我们知道,ExecutorService是一个抽象出线程池的一个接口,然后我们在使用线程池的时候,用的是Executors工具类中的一系列newCachedThreadPool() 等类似的方法,这些 ...

  3. 硬核干货:4W字从源码上分析JUC线程池ThreadPoolExecutor的实现原理

    前提 很早之前就打算看一次JUC线程池ThreadPoolExecutor的源码实现,由于近段时间比较忙,一直没有时间整理出源码分析的文章.之前在分析扩展线程池实现可回调的Future时候曾经提到并发 ...

  4. 12.ThreadPoolExecutor线程池原理及其execute方法

    jdk1.7.0_79  对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任 ...

  5. java 线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用。

    转载请声明出处谢谢!http://www.cnblogs.com/linguanh/ 这里主要使用Executors中的4种静态创建线程池实例方法中的 newFixedThreadPool()来举例讲 ...

  6. java线程池ThreadPoolExecutor使用简介

    一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...

  7. java线程池ThreadPoolExecutor理解

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  8. 线程池ThreadPoolExecutor、Executors参数详解与源代码分析

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. ThreadPoolExecutor数据成员 Private final Atom ...

  9. 线程池ThreadPoolExecutor

    线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maxi ...

随机推荐

  1. 如何利用C# Roslyn编译器写一个简单的代码提示/错误检查?

    OK, 废话不多说,这些天在写C#代码时突然对于IDE提示有了一些想法,之前也有了解过,不过并没有深入. 先看个截图: 一段再简单不过的代码了,大家注意看到 count 字段下面的绿色波浪线了吗,我们 ...

  2. 媒体查询文字大小.html

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. 关于GMT UTC CST和Linux时区设置

    GMT即格林威治时间:UTC即全球统一时间:GMT和UTC的时间是一样的 北京时间是东八区,即GMT+8或者UTC+8 CST:Central Standard Time (CST) is 6 hou ...

  4. jwt token

    1 ,session 认证机制: ,用户登录,传递用户名和密码给客户端 ,服务器进行用户名和密码的校验,如果校验成功,将用户保存到session ,将sessionid通过cookie返回给客服端,客 ...

  5. Office中国在这个开个博客

    Office中国在这个开个博客,先来show一下我的网站 Office中国/Access中国  http://www.office-cn.net Office中国百科:   http://baike. ...

  6. Java IO编程——文件拷贝

    在操作系统里面有一个copy命令,这个命令的主要功能是可以实现文件的拷贝处理,现在要求模拟这个命令,通过初始化参数输入拷贝的源文件路径与拷贝的目标路径实现文件的拷贝处理. 需求分析: ·需要实现文件的 ...

  7. 修改tomcat默认使用的jdk版本

    1.windows平台 在csetclasspath.bat文件开头加上如下两句(指定JDK): set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_79  se ...

  8. Java自动化测试框架-10 - TestNG之测试结果篇

    1.-测试结果 1.1-成功,失败和断言 测试被认为是成功的,如果它不引发任何异常完成,还是它扔的预期异常(请参阅文档expectedExceptions属性上找到的@Test注释). 您的测试方法通 ...

  9. 使用Typescript重构axios(十八)——请求取消功能:总体思路

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  10. 使用Typescript重构axios(二十九)——添加baseURL

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...