1. Threads 和 Runnables

  所有的现代操作系统都通过进程和线程来支持并发。进程是通常彼此独立运行的程序的实例,比如,如果你启动了一个Java程序,操作系统产生一个新的进程,与其他程序一起并行执行。在这些进程的内部,我们使用线程并发执行代码,因此,我们可以最大限度的利用CPU可用的核心(core)。Java从JDK1.0开始执行线程。在开始一个新的线程之前,你必须指定由这个线程执行的代码,通常称为task。这可以通过实现Runnable:一个定义了一个无返回值无参数的run()方法的函数接口,如下面的代码所示:

Runnable task = () -> {     //JDK 1.8中的 Lambda 表达式
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
};
task.run(); Thread thread = new Thread(task);
thread.start(); System.out.println("Done!");

2. java 线程池的使用

  上面继承Thread类和实现Runnable接口,可以实现多线程。但是如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池,首先我们从最核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,最后讨论了一下如何合理配置线程池的大小。

  Java中的ThreadPoolExecutor类,java..uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。下面我们来看一下ThreadPoolExecutor类的具体实现源码。

public class ThreadPoolExecutor extends AbstractExecutorService {

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

从上面的代码可以得知,ThreadPoolExecutor继承了AbstractExecutorService类,并提供了四个构造器,事实上,通过观察每个构造器的源码具体实现,发现前面三个构造器都是调用的第四个构造器进行的初始化工作。下面解释下一下构造器中各个参数的含义: 

  coorPoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;unit参数:keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:

TimeUnit.DAYS;               //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒

workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:

 

对Java并发编程的几点思考的更多相关文章

  1. 【转】关于Java并发编程的总结和思考

    一.前言 就是想学习Java并发编程了,所以转载一下这篇认为还不错的博客~ 二.正文 编写优质的并发代码是一件难度极高的事情.Java语言从第一版本开始内置了对多线程的支持,这一点在当年是非常了不起的 ...

  2. 关于Java并发编程的总结和思考

    编写优质的并发代码是一件难度极高的事情.Java语言从第一版本开始内置了对多线程的支持,这一点在当年是非常了不起的,但是当我们对并发编程有了更深刻的认识和更多的实践后,实现并发编程就有了更多的方案和更 ...

  3. Java并发编程:进程和线程之由来

    Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...

  4. java并发编程:进程和线程

    java并发编程涉及到很多内容,当然也包括多线程,再次补充点相关概念 原文地址:http://www.cnblogs.com/dolphin0520/p/3910667.html 一.操作系统中为什么 ...

  5. Java并发编程:进程和线程之由来__进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能

    转载自海子:http://www.cnblogs.com/dolphin0520/p/3910667.html Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨 ...

  6. Java并发编程:进程和线程的由来(转)

    Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...

  7. Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  8. java并发编程系列七:volatile和sinchronized底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  9. Java并发编程--BlockingQueue

    概述 BlockingQueue支持两个附加操作的Queue:1)当Queue为空时,获取元素线程被阻塞直到Queue变为非空:2)当Queue满时,添加元素线程被阻塞直到Queue不满.Blocki ...

随机推荐

  1. js显示yyyy年mm日dd天 星期几 的格式日期

    js代码: <script type="text/javascript"> var today = new Date(); var week; //存储星期几 var ...

  2. python2.7和python3共存

    python2.7和python3共存 原本装了python,玩nodejs的时候需要node-gyp来编译依赖,无赖这货需要python2.5<v<3.0,那就弄两个版本吧 转载自 ht ...

  3. TSql Output 用法

    第一部分:TSql Output 关键字有两种应用场景 1,作为存储过程的参数类型,从存储过程中返回数据 2,返回受 INSERT.UPDATE.DELETE 或 MERGE 语句影响的各行中的信息, ...

  4. JSP网站开发基础总结《三》

    经过前两篇的总结,我想大家一定迫不及待的想学习今天的关于jsp与mysql的数据库连接的知识了.既然需要连接mysql数据库,你首先需要保证你的电脑已经安装过mysql数据库,mysql数据库的安装步 ...

  5. 【总结】探索Newlife组件:服务代理利器XAgent的前世今生

         本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html Newlife XCode组件相关文章目录:http://www.cn ...

  6. backbone库学习-Collection

    backbone库的结构: http://www.cnblogs.com/nuysoft/archive/2012/03/19/2404274.html 本文所有例子来自于http://blog.cs ...

  7. mac+apache+php+phpmyadmin集成php开发环境配置

    刚开始才接触php才发现macos还是比较强大了,macbook不仅是时尚达品还很实用哦. --------------他山之石-------------------------- http://da ...

  8. 碉堡了! 纯 CSS 绘制《辛普森一家》人物头像

    这篇文章给大家分享一组纯 CSS 绘制的<辛普森一家>人物头像.<辛普森一家>(The Simpsons)是马特·格勒宁为美国福克斯广播公司创作的一部动画情景喜剧.该剧通过对霍 ...

  9. CSS 魔法系列:纯 CSS 绘制图形(心形、六边形等)

    <CSS 魔法系列>继续给大家带来 CSS 在网页中以及图形绘制中的使用.这篇文章给大家带来的是纯 CSS 绘制五角星.六角形.五边形.六边形.心形等等. 我们的网页因为 CSS 而呈现千 ...

  10. js组件在线编辑器插件、图表库插件、文件树插件

    在线编辑器插件: 一.kindeditor 二.UEditor 图表库插件: 一.echart 二.highchart 文件树插件: 一.zTree -- jQuery 树插件 http://www. ...