当前位置: 首页 > news >正文

线程池及并发编程基础总结

常用线程池

可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程

ExecutorService threadPool = Executors.newFixedThreadPool(3);// 创建可以容纳3个线程的线程池

根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们

ExecutorService threadPool = Executors.newCachedThreadPool();// 线程池的大小会根据执行的任务数动态分配

使用单个 worker 线程的 Executor,以无界队列方式来运行该线程

ExecutorService threadPool = Executors.newSingleThreadExecutor();// 创建单个线程的线程池,如果当前线程在执行任务时突然中断,则会创建一个新的线程替代它继续执行任务

可安排在给定延迟后运行命令或者定期地执行的线程池

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);// 效果类似于Timer定时器

JVM内部同步机制和JVM外部同步机制

内部同步机制

  • static的强制同步机制
  • synchronized的同步机制:可以使用this、类字面常亮、特有锁对象(专门为加锁使用,无实际意义的对象,此种方式效率更高。)

外部同步机制

ReentrantLock(可重入的锁)

  • synchronized关键字同步的时候,等待的线程将无法控制,只能死等。

解决方式:ReentrantLock可以使用tryLock(timeout, unit)方法去控制等待获得锁的时间,也可以使用无参数的tryLock方法立即返回,这就避免了死锁出现的可能性。

  • synchronized关键字同步的时候,不保证公平性,因此会有线程插队的现象。

解决方式:ReentrantLock可以使用构造方法ReentrantLock(fair)来强制使用公平模式,这样就可以保证线程获得锁的顺序是按照等待的顺序进行的,而synchronized进行同步的时候,是默认非公平模式的,但JVM可以很好的保证线程不被饿死。

ReentrantLock有这样一些优点,当然也有不足的地方。最主要不足的一点,就是ReentrantLock需要开发人员手动释放锁,并且必须在finally块中释放。

JVM内部条件控制机制和JVM外部条件控制机制

JVM内部条件控制机制

在Object中,有一个wait的本地方法;它可以用来协调线程之间的协作。

wait一般情况下最常用的场景是构造一个花销非常大的对象的时候,比如JDK动态代理在生成代理类的时候就使用了这种方式。JDK6在生成一个代理类之前,会先检测一个是否正在生成中的标识,如果正在生成的话,JDK6就会在对象上等待,直到正在生成的代理类生成完毕,然后直接从缓存中获取。

wait,notify和notifyAll方法在使用前,必须获取到当前对象的锁,否则会告诉你非法的监控状态异常。还有一点,则是如果有多个线程在wait等待,那么调用notify会随机通知其中一个线程,而不会按照顺序通知。换句话说,notify的通知机制是非公平的,notify并不保证先调用wait方法的线程优先被唤醒。notifyAll方法则不存在这个问题,它将通知所有处于wait等待的线程。

JVM外部条件控制机制

JDK的类库中,有这样的一个类Condition,来弥补wait方法本身的不足。

  • wait方法当使用带参数的方法wait(timeout)或者wait(timeout,nanos)时,无法反馈究竟是被唤醒还是到达了等待时间,大部分时候,我们会使用循环(就像上面的例子一样)来检测是否达到了条件。

解决方式:Condition可以使用返回值标识是否达到了超时时间。

  • 由于wait,notify,notifyAll方法都需要获得当前对象的锁,因此当出现多个条件等待时,则需要依次获得多个对象的锁,这是非常恶心麻烦且繁琐的事情。

解决方式:Condition之需要获得Lock的锁即可,一个Lock可以拥有多个条件。

JVM外部 线程协作

CountDownLatch

这个类是为了帮助猿友们方便的实现一个这样的场景,就是某一个线程需要等待其它若干个线程完成某件事以后才能继续进行。

CyclicBarrier

这个类是为了帮助猿友们方便的实现多个线程一起启动的场景,就像赛跑一样,只要大家都准备好了,那就开始一起冲。比如下面这个程序,所有的线程都准备好了,才会一起开始执行。

Semaphore

这个类是为了帮助猿友们方便的实现控制数量的场景,可以是线程数量或者任务数量等等。

Exchanger

这个类是为了帮助猿友们方便的实现两个线程交换数据的场景,使用起来非常简单。

参考文档:

  • http://blog.csdn.net/ghsau/article/details/7443324
  • http://www.cnblogs.com/zuoxiaolong/p/con2.html

相关文章:

  • Ztree当节点没有下级时不显示下拉图标
  • Bootstrap表单验证插件bootstrapValidator使用方法整理
  • 寻找多数元素问题
  • chattr加锁文件引起yum更新时报错处理
  • Java迭代器
  • extjs4学习之配置
  • iptables练习
  • 大数据分析之hadoop的基本学习1-VMwae+Ubuntu
  • JavaScript的two-sum问题解法
  • nginx ssl
  • 关于Java内部类的初始化
  • noi 1.5 45:金币
  • nginx location配置
  • ArcGIS Engine 编辑- IWorkspaceEdit
  • Access-Control-Allow-Origin与跨域
  • 【Linux系统编程】快速查找errno错误码信息
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android框架之Volley
  • Java读取Properties文件的六种方法
  • js递归,无限分级树形折叠菜单
  • spring security oauth2 password授权模式
  • Vue ES6 Jade Scss Webpack Gulp
  • Vue 动态创建 component
  • vue自定义指令实现v-tap插件
  • Web设计流程优化:网页效果图设计新思路
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 盘点那些不知名却常用的 Git 操作
  • 前端存储 - localStorage
  • 前端之Sass/Scss实战笔记
  • 一天一个设计模式之JS实现——适配器模式
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • NLPIR智能语义技术让大数据挖掘更简单
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ​用户画像从0到100的构建思路
  • #include到底该写在哪
  • #stm32整理(一)flash读写
  • #传输# #传输数据判断#
  • #图像处理
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (C语言)fread与fwrite详解
  • (二)hibernate配置管理
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (十八)三元表达式和列表解析
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET下ASPX编程的几个小问题
  • 。Net下Windows服务程序开发疑惑
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [BZOJ4016][FJOI2014]最短路径树问题