为什么80%的码农都做不了架构师?>>>   

相信大多数接触过多线程的朋友都会有这样的困惑,明明使用了多线程,为何还是一团糟?用下面两幅图再合适不过了: 理想情况下的多线程VS 现实中:

或者像这样:

像这样:

太糟心了实在是,是时候对多线程了解的更透彻一点了。我们从线程说起,

| 什么是线程

线程是比进程更小的运行单位,一个进程只少有一个(主线程)或多个线程,每个线程完成不同的任务;而每个进程都需要操作系统为其分配独立的内存地址空间,而同一进程中的所有线程在同一内存地址空间,它们共享同一块内存空间中的资源。 因此,相较进程,线程间 1.可共享数据;2.不必重新为线程分配系统资源,代价小; java中内置了多线程功能的支持,也为我们使用多线程提供了方便;

附上线程使用的方法: 1、继承Thread类 2、实现Runnable接口 3、通过Callable和Future创建线程

线程生命周期快速预览:

新建状态-》就绪-》运行-》阻塞-》死亡;

线程管理快速预览:

1.睡眠sleep;2.让步yield;3.合并join;4.设置优先级Priority;5.设置守护线程Deamon;6.正确结束线程;

线程同步快速预览: 1.使用同步方法,synchronized关键字修饰的方法; 2.使用同步代码块,synchronized关键字修饰的代码块; 3.使用volatile; 4.使用重入锁,Lock

线程通信快速预览: 1.wait()、notify()和notifyAll()方法; 2.使用Condition; 3.使用阻塞队列,BlockingQueue;

| 什么是多线程

多个线程并发执行; 字面上理解很简单,但真正做到多个线程并发执行,还是需要下功夫的,需要掌握线程的生命周期,处理好线程的同步问题,线程之间的通信,以及最最不愿看到的线程的死锁的处理。

| 为什么要用线程池:

在java中,如果每个请求到达就创建一个新线程,开销是相当大的。在实际使用中,服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。

1.减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

| 线程池的组成:

线程池管理器、工作线程、任务列队、任务接口等部分

线程池管理器至少有下列功能:创建线程池,销毁线程池,添加新任务。 工作线程是一个可以循环执行任务的线程,在没有任务时将等待。 任务接口是为所有任务提供统一的接口,以便工作线程处理。任务接口主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等。

| 相关API

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

ThreadPoolExecutor的完整构造方法的签名是:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, RejectedExecutionHandler handler) .

各个参数说明: corePoolSize - 池中所保存的线程数,包括空闲线程。 maximumPoolSize - 池中允许的最大线程数。 keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。 unit - keepAliveTime 参数的时间单位。 workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。 threadFactory - 执行程序创建新线程时使用的工厂。 handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。 ThreadPoolExecutor是Executors类的底层实现。

在JDK帮助文档中,有如此一段话:

“强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池) Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。”

比较重要的几个类:

ExecutorService 真正的线程池接口。 ScheduledExecutorService 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。 ThreadPoolExecutor ExecutorService的默认实现。 ScheduledThreadPoolExecutor 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。

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

  1. newSingleThreadExecutor

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

  1. newFixedThreadPool

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

  1. newCachedThreadPool

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

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

| 实例:

一般情况下,掌握上述几种线程池就可以了,特殊场景下要自定义一个线程池的除外。举个简单例子:

public class ExecutorTest {private static void doPrint(ExecutorService threadPool) {for (int i = 1; i <= 5; i++) {final int taskID = i;threadPool.submit(new Runnable() {@Overridepublic void run() {for (int i = 1; i <= 5; i++) {try {Thread.sleep(20);// 为了测试出效果,让每次任务执行都需要一定时间} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第" + taskID + "次任务的第" + i + "次执行");}}});}threadPool.shutdown();// 任务执行完毕,关闭线程池}public static void main(String[] args) {// 创建可以容纳3个线程的线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 线程池的大小会根据执行的任务数动态分配ExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 创建单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程替代它继续执行任务ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();// 效果类似于Timer定时器ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);//        doPrint(fixedThreadPool);
//        doPrint(cachedThreadPool);
//        doPrint(singleThreadPool);doPrint(scheduledThreadPool);}
}

坚持原创技术分享,您的支持将鼓励我继续创作!

转载于:https://my.oschina.net/Gxhpro/blog/850643

掌握JAVA多线程的利器-线程池相关推荐

  1. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  2. Java多线程-新特性-线程池

    Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...

  3. Java多线程设计模式(4)线程池模式

    前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将"委托消息的一端"和"执行消息的一端&qu ...

  4. java多线程抽奖_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码...

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  5. Java多线程案例之线程池

    文章目录 一. 线程池概述 1. 什么是线程池 2. Java标准库提供的线程池 二. 线程池的简单实现 一. 线程池概述 1. 什么是线程池 线程池和和字符串常量池, 数据库连接池一样, 都是为了提 ...

  6. java多线程并发及线程池

    线程的常用创建方式 1.继承Thread类创建线程类 public class FirstThreadTest extends Thread {public void run(){System.out ...

  7. java多线程编程之线程池技术全面解读

    在多线程编程时,创建线程是十分消耗资源的,当线程创建过多时,便会引发内存溢出,因此引入了线程池技术. 目录 线程池的优势 线程池的创建&使用 线程池的工作原理 线程池的参数 功能线程池 线程池 ...

  8. Java多线程系列 JUC线程池05 线程池原理解析(四)

    转载 http://www.cnblogs.com/skywang12345/p/3544116.html  https://blog.csdn.net/programmer_at/article/d ...

  9. Java多线程系列 JUC线程池01 线程池框架

    转载  http://www.cnblogs.com/skywang12345/p/3509903.html 为什么引入Executor线程池框架 new Thread()的缺点 1. 每次new T ...

最新文章

  1. Oracle入门(十四.1)之PL / SQL简介
  2. Maven依赖的是本地工程还是仓库jar包?
  3. java质因数算法_Java实现的质因数分解操作示例【基于递归算法】
  4. [Regular] 4、正则表达式的匹配原理原则
  5. 矩阵运算_迹的相关性质
  6. Nginx集群之基于Redis的WebApi身份验证
  7. Hadoop在master查看live nodes为0解决方案
  8. python做购物系统的实训报告_网上购物系统实训总结
  9. 揭秘淘宝286亿海量图片存储与处理架构(转)
  10. Error in cor(xdata) : 'x'必需为数值
  11. android+widget日历开发,安卓日历小部件源码(AppWidgetProvider)
  12. Android手机ram大小,什么是手机RAM内存?手机RAM内存越大越好吗?
  13. linux中退格出现乱码,SSH中的SQL命令按退格键出现乱码的有关问题解决
  14. 恒天然NZMP品牌干酪在2018年国际奶酪大赛中荣获八枚奖牌
  15. 究竟什么才是云计算 云计算的优势都有哪些
  16. 个人英文小词典--抽取英文阅读重要的名词、动词、形容词、副词并输出其翻译结果
  17. 基于xml的数据交换技术
  18. draw.io和plantuml替代visio画图工具
  19. 【转载】2018衡水中学高考成绩再次刷爆朋友圈,文末衡水版《凉凉》别有一番滋味!
  20. Macbook Pro 外接显卡实现Tensorflow GPU运行之MacOS系统重装

热门文章

  1. 艰难万苦配置postfix+ldap+extmail+.......
  2. 嵌入式EasyHMI V0.1版终于推出,C#真是软件开发的利器
  3. 计算机原理与基础 —— (皇帝身边的小太监----寄存器)
  4. Python_第一堂课
  5. node执行cmd命令方法
  6. HDU_oj_2021 发工资喽
  7. Ibatisnet示例:npetshop学习一
  8. [转]Git详解之五 分布式Git
  9. 分布式消息通信ActiveMQ原理-持久化策略-笔记
  10. [译]React高级话题之Context