博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程池及并发编程基础总结
阅读量:7037 次
发布时间:2019-06-28

本文共 2120 字,大约阅读时间需要 7 分钟。

常用线程池
可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程
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://www.cnblogs.com/rwxwsblog/p/6231538.html,如需转载请自行联系原作者
你可能感兴趣的文章
教你如何删除WIN7系统文件以及无法删除的文件
查看>>
Note 741478 - FAQ: Materialized views
查看>>
Everything(文件搜索神器)
查看>>
KVC在定义Model类中的妙用
查看>>
笔试题目-J2EE
查看>>
jdk分析工具:jps和jstack
查看>>
如何将java源码打成jar包
查看>>
参加Tech.ED2008(微软技术大会)上海站
查看>>
NPM版本号
查看>>
[Android] 判断手机上是否安装了某个程序
查看>>
安装OpenLDAP步骤
查看>>
自我激励的20种方法
查看>>
Netbeans 8.2将支持PHP 7
查看>>
Redis 一二事 - 在spring中使用jedis 连接调试单机redis以及集群redis
查看>>
DotNetCore跨平台~linux上还原自主nuget包需要注意的问题
查看>>
《深入理解Nginx:模块开发与架构解析》一2.4 用HTTP核心模块配置一个静态Web服务器...
查看>>
Spotify投资方:与其上市 不如卖给Facebook吧
查看>>
EMC股东98%赞成票 果断批准戴尔并购案
查看>>
简单入门循环神经网络RNN:时间序列数据的首选神经网络
查看>>
告别盲目跟风 从事智能家居需具备哪些条件?
查看>>