一.普通线程和线程池的对比

new Thread的弊端如下:

a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。

相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。

二、Java 线程池

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

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

为什么要用线程池:

1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

线程池的四种形式:

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

比较重要的几个类:

ExecutorService

真正的线程池接口。

ScheduledExecutorService

能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。

ThreadPoolExecutor

ExecutorService的默认实现。

ScheduledThreadPoolExecutor

继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。

1. newSingleThreadExecutor

创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

2.newFixedThreadPool

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

3. newCachedThreadPool

创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

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

4.newScheduledThreadPool

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

线程池的实现:

  1. //声明线程池对象
  2. private static ThreadPoolExecutor executor = null;
  3.  
  4. //初始化线程池对象,两种方式
  5. 1)构造函数初始化
  6. executor =new ThreadPoolExecutor(1, //核心线程数
  7. maximumPoolSize, //线程池最大容量大小
  8. 15 * 60 * 1000,//线程池空闲时,线程存活的时间,这里是以毫秒为时间单位
  9. TimeUnit.MILLISECONDS, // 时间单位
  10. new SynchronousQueue<Runnable>(), //任务队列
  11. new ThreadFactory() {//线程工厂
  12. public Thread newThread(Runnable r) {
  13. return new Thread(r, "Thread-BatchCPSService");//这个参数是命名线程名,info级别的日志就能看到
  14. }
  15. },
  16. new ThreadPoolExecutor.CallerRunsPolicy()); //线程拒绝策略
  17. 2)设置属性,需要实现setExecutor方法
  18. MultipleThreadUtil.setExecutor(new ThreadPoolExecutor(1,
  19. maximumPoolSize,
  20. 15 * 60 * 1000,
  21. TimeUnit.MILLISECONDS,
  22. new SynchronousQueue<Runnable>(),
  23. new ThreadFactory() {
  24. public Thread newThread(Runnable r) {
  25. return new Thread(r, "Thread-BatchCPSService");
  26. }
  27. },
  28. new ThreadPoolExecutor.CallerRunsPolicy()));

线程池的使用:

  1. ThreadPoolExecutor executor = MultipleThreadUtil.getThreadPoolExecutor();
  2. // 采用多线程方式调用
  3. if (executor != null) {
  4. executor.submit(new Callable<Object>() {
  5. public Object call() throws Exception {
  6. //业务处理
  7. return null;//如果需要业务处理的返回结果,需要实现Future
  8. }
  9. });
  10. }

Java线程池学习心得的更多相关文章

  1. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  2. Java 线程池学习

    Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...

  3. JAVA线程池学习,ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?

    初学者很容易看错,如果没有看到spring或者JUC源码的人肯定是不太了解的. ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JD ...

  4. Java线程池学习总结

    一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...

  5. 【Java多线程】线程池学习

    Java线程池学习 众所周知,Java不仅提供了线程,也提供了线程池库给我们使用,那么今天来学学线程池的具体使用以及线程池基本实现原理分析. ThreadPoolExecutor ThreadPool ...

  6. 转:JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue

    从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构 ...

  7. 【Java线程池快速学习教程】

    1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...

  8. Java线程池快速学习教程

    1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...

  9. (转载)JAVA线程池管理

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...

随机推荐

  1. Ubuntu切换阿里源

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...

  2. 22-python爬虫解决gbk乱码问题

    转载自: python爬虫解决gbk乱码问题   今天尝试了下爬虫,爬取一本小说,忘语的凡人修仙仙界篇,当然这样不好,大家要支持正版. 爬取过程中是老套路,先获取网页源代码 # -*- coding: ...

  3. ScrollView中嵌套ListView的问题

    网上关于怎样在ScrollView中嵌套ListView的讨论有很多,我大概是搜索了一下,简单总结如下: 1.不要在ScrollView中嵌套ListView a.用一个LinearLayout来代替 ...

  4. JavaScript 语法总结3

    1. 数组初始化可以跳着来  var s = [1,2,,,,6]; // 中间省略的元素为undefined 2. 函数定义表达式:  var f = function(args){ return ...

  5. 看图说说JVM新生代垃圾收集器

  6. (3)-JSONObject的过滤设置

    我们通常对一个json串和java对象进行互转时,经常会有选择性的过滤掉一些属性值.例如下面的类:   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

  7. 自定义Team Foundation Server (TFS) 与Project Professional的集成字段

    用户可以象使用Office Excel一样,使用Project Professional连接TFS,将数据下载到本地修改,并且发布到TFS服务器上,如果你习惯使用Project来计划你的项目,那么Pr ...

  8. Spring中ApplicationContext和beanfactory区别---解析一

    BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是一种典型的BeanFactory.原始的BeanFactory无法支持spring的许多插件,如AOP ...

  9. Docker私有仓库Registry实战

    参考: https://www.cnblogs.com/soar1688/p/6828329.html 1. 关于Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在 ...

  10. LightOJ 1220 Mysterious Bacteria(唯一分解定理 + 素数筛选)

    http://lightoj.com/volume_showproblem.php?problem=1220 Mysterious Bacteria Time Limit:500MS     Memo ...