
java并发编程
文章平均质量分 79
aitangyong
成长最快、最好的方式就是交流和总结!
展开
-
JDK并发工具包CompletionService和ExecutorCompletionService的好处和使用场景
《Java并发编程实践》一书6.3.5节CompletionService:Executor和BlockingQueue,有这样一段话: "如果向Executor提交了一组计算任务,并且希望在计算完成后获得结果,那么可以保留与每个任务关联的Future,然后反复使用get方法,同时将参数timeout指定为0,从而通过轮询来判断任务是否完成。这种方法虽然可行,但却有些繁琐。幸运的是,还有一种原创 2014-07-27 13:39:11 · 6699 阅读 · 3 评论 -
JDK7中TransferQueue的使用以及TransferQueue与SynchronousQueue的差别
1.transfer(E e)若当前存在一个正在等待获取的消费者线程,即立刻将e移交之;否则将元素e插入到队列尾部,并且当前线程进入阻塞状态,直到有消费者线程取走该元素。2.ryTransfer(E e, long timeout, TimeUnit unit) 若当前存在一个正在等待获取的消费者线程,会立即传输给它; 否则将元素e插入到队列尾部,并且等待被消费者线程获取消费掉。若在指定的时间内元素e无法被消费者线程获取,则返回false,同时该元素从队列中移除。3.tryTransfer(E e)若当原创 2015-06-12 16:48:06 · 5256 阅读 · 0 评论 -
java主线程结束和子线程结束之间的关系
最近在和同事讨论java主线程和子线程之间的关系,自己也到网上搜索了下,发现各种答案都有,有些还是互相矛盾的。经过测试自己得出以下几个结论,跟大家分享下,如果有错误,欢迎大牛指正,帮助我这只小菜鸟。废话不多说,直接上结论:(一)Main线程是个非守护线程,不能设置成守护线程。 这是因为,main线程是由java虚拟机在启动的时候创建的。main方法开始执行的时候,原创 2013-11-21 20:31:21 · 19979 阅读 · 13 评论 -
LockSupport的park和unpark的基本使用,以及对线程中断的响应性
LockSupport是JDK中比较底层的原创 2014-08-04 22:26:35 · 26775 阅读 · 10 评论 -
java并发编程实践学习(三)JVM的server模式和client模式
《java并发编程实践》作者讲述volatile关键字的时候,在书中的注脚提到了JVM的server模式和client模式。以前自己从来没有听说过这个东西,不得不感概自己知识面的狭窄,编程的世界浩瀚!于是上网上看一些别人的博客,扫个盲,这里记录下一些相关概念。 首先说下server模式和client模式的区别。Jvm有client和server两个版本,分别针对桌面应用程序和服务端原创 2014-04-01 20:36:05 · 2175 阅读 · 0 评论 -
使用JUC并发工具包的Lock和Condition,实现生产者和消费者问题中的有界缓存
JDK5.0之前,用java实现生产者和消费者的唯一方式就是使用synchronized内置锁和wait/notify条件通知机制。JDK5.0之后提供了显示锁Lock和条件队列Condition,与内置锁和内置条件队列相对应,但是显示的锁和条件队列,功能更强大,更灵活。此外JDK5.0之后还提供了大量很有用的并发工具类,如BlockingQueue等,基于这些数据结构,能够方便、快速、高效的构建原创 2014-08-07 21:23:03 · 1717 阅读 · 2 评论 -
java并发编程实践学习(四)对象的发布和逸出之this逃逸
《java并发编程实践》的第三章,对象的发布和逸出,作者提到了2种常见的对象逸出情况:在构造函数中注册事件监听,在构造函数中启动新线程。示例代码如下:public class ThisEscape { public ThisEscape(EventSource source) { source.registerListener( new Even原创 2014-05-06 22:20:42 · 5467 阅读 · 0 评论 -
一步步学习java并发编程模式之Active Object模式(一)什么是active object
最近在阅读世界级软件开发大师Robert C. Martin的名著《敏捷软件开发原则、模式与实践》,在讲述命令模式的时候,Bob大叔提到了命令模式的一个使用场景:Active Object。刚开始不知道这是什么,看例子DelayedTyper的时候,也是云里雾里不太理解。百度了一下后,才知道Active Object是并发编程一种常用的模式。看了 别人写的博客,也是半知半解,打算写一系列关于该模式原创 2014-03-13 21:50:20 · 2838 阅读 · 0 评论 -
一步步学习java并发编程模式之Active Object模式(二)java实现异步调用
一步步学习Active Object并发编程模式和JDK并发工具包的下Future和Excuetor等。通过自己写的例子和理解,和大家交流学习原创 2014-03-13 22:14:15 · 2117 阅读 · 2 评论 -
一步步学习java并发编程模式之Active Object模式(三)java实现active object
在 Active Object 模式中,主要有以下几种类型的参与者:代理 (proxy) ,方法请求(method request),activation list,调度者 (scheduler),servant,future.原创 2014-03-16 16:41:01 · 3142 阅读 · 0 评论 -
一步步学习java并发编程模式之Active Object模式(四)改进后的java实现
可复用的active object框架原创 2014-03-16 22:40:57 · 1279 阅读 · 0 评论 -
一步步学习java并发编程模式之Active Object模式(五) 使用JDK的内置实现
通过上一篇博客 一步步学习 java并发编程模式之Active Object模式(四) 我们发现,增加一个类似的服务,天气服务的所有代码都需要重写,虽然这些代码很相似,但是仍然不能复用。这是因为我们违反了面向对象的DIP原则,没有对代码进行合适的抽象。设计其实就是抽象,将业务相关代码和业务无关代码解耦、复杂多变的细节和相对稳定的抽象解耦,彼此通过接口进行依赖。完全与业务无关代码,基本上不再需要我们原创 2014-05-18 09:14:38 · 927 阅读 · 0 评论 -
java并发编程实践学习(一)java的类锁和对象锁
最近在看Java Concurrent in Practice(java并发编程实践),发现自己对java的线程、锁等机制,理解很肤浅,学习的也不够全面。打算借着这本书,全面的学习下JDK的并发包和一些线程相关的理论知识,填补自己的空白,也可以和大家交流,理解不正确的地方,欢迎指正。第一篇博客,先简单的介绍下类锁和对象锁的概念,和关键字synchronized。原创 2014-03-31 20:50:22 · 2215 阅读 · 0 评论 -
学习java线程状态和看懂thread dump文件中的线程信息
t1 : 这个是线程名称,可以在new Thread()对象的时候指定,或者调用Thread.setName。有了这个名称,搜索thread dump的时候更加方便。这也就是为什么,一般创建线程的时候需要指定线程名称,而不是使用默认的名称。prio=6 : 这个代表的是线程的优先级priority,也可以通过Thread类中的API修改。实际应用中,一般不会设置该属性,没有太大的用处。tid : Java的线程Id (这个线程在当前虚拟机中的唯一标识)。nid : 线程本地标识,是线程在操作系统中的标原创 2014-09-23 20:18:49 · 13238 阅读 · 3 评论 -
似懂非懂的SynchronousQueue和长度为1的BlockingQueue
(阅读ArrayBlockingQueue源码,很容易知道有界阻塞队列的长度至少为1,也就是至少能缓存下一个数据。长度为0的阻塞队列是没有意义的,因为生产者不能生产,消费者不能消费。但是SynchronousQueue的javadoc文档提到A synchronous queue does not have any internal capacity, not even a capacity of one。也就说同步队列的容量是0,不会缓存数据。可以看到同步队列有这样的特性:producer waits u原创 2014-08-19 19:32:26 · 5559 阅读 · 1 评论 -
java.util.concurrent.locks.Lock类的lock和lockInterruptibly方法的区别
什么是可中断的锁获取呢?就是:线程在等待获取锁的过程中,是否能够响应中断,以便在被中断的时候能够解除阻塞状态,而不是傻傻地一直在等待。java对象的内置锁(synchronized)就是一种不可中断的锁,也就是说如果一个线程在等待获取某个对象的内置锁,就算是该线程被其他线程中断,该线程仍然继续等待内置锁,而不是解除阻塞状态,也不会抛出InterruptedException。Lock类原创 2014-07-30 13:43:40 · 1790 阅读 · 0 评论 -
JDK读写锁ReadWriteLock的升级和降级问题
JDK提供了写锁接口ReadWriteLock和它的实现ReentrantReadWriteLock。要实现一个读写锁,需要考虑很多细节,其中之一就是锁升级和锁降级的问题。什么是升级和降级呢?ReadWriteLock的javadoc有一段话:Can the write lock be downgraded to a read lock without allowing an interven原创 2014-07-31 14:23:14 · 10613 阅读 · 1 评论 -
可重入锁的获取和释放需要注意的一点儿事
什么是可重入锁,不可重入锁呢?"重入"字面意思已经很明显了,就是可以重新进入。可重入锁,就是说一个线程在获取某个锁后,还可以继续获取该锁,即允许一个线程多次获取同一个锁。比如synchronized内置锁就是可重入的,如果A类有2个synchornized方法method1和method2,那么method1调用method2是允许的。显然重入锁给编程带来了极大的方便。假如内置锁不是可原创 2014-07-31 09:06:57 · 3978 阅读 · 0 评论 -
我对java中任务取消和线程中断的一点儿理解
在JDK中任务就是一个Runnable或Callable对象,线程是一个Thread对象。任务运行在单个线程或者是线程池ExecutorService中。我们知道,让线程死亡的方式有2种:正常完成和未捕获的异常。如果想让任务结束,也是只有这2种方式。原创 2014-08-07 20:42:11 · 2601 阅读 · 0 评论 -
理解ThreadPoolExecutor源码(二)execute函数的巧妙设计和阅读心得
使用这么多if-else就是为了性能考虑,减小锁的使用范围,避免execute方法整个执行过程中都持有mainLock锁。可以看到只有调用addIfUnderCorePoolSize、ensureQueuedTaskHandled、addIfUnderMaximumPoolSize这3个方法才需要持有锁。如果新提交的任务,不会进入这3个方法,那么就不需要持有锁。我们来看下,execute方法的设计是否能够有效地减少进入这3个方法的次数,实现快进快出。原创 2014-08-28 23:05:42 · 2604 阅读 · 0 评论 -
理解ThreadPoolExecutor源码(一)线程池的corePoolSize、maximumPoolSize和poolSize
我们知道,受限于硬件、内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值。也就是说ThreadPoolExecutor管理的线程数量是有界的。线程池就是用这些有限个数的线程,去执行提交的任务。然而对于多用户、高并发的应用来说,提交的任务数量非常巨大,一定会比允许的最大线程数多很多。为了解决这个问题,必须要引入排队机制,或者是在内存中,或者是在硬盘等容量很大的原创 2014-09-13 10:19:13 · 51657 阅读 · 4 评论 -
理解并发编程中的重要概念:指令重排序和指令乱序执行
看过了很多介绍指令重排序的文章,可惜由于自己硬件和计算机理论知识缺乏,很难理解深层次的奥秘和实现原理。不过也有很多帖子,讲的浅显易懂,使用的例子很形象。大牛就是能用简单的解释和通俗的比喻,给我们讲明白很高深的东西。这里做个摘抄和总结,和大家分享下,希望大家能够对指令重排序有个形象的认识,不至于在并发编程中犯一些简单的错误。如果理解有错误,希望看到的大神指正。 从源码变成可以被机器(或虚拟机)识别的程序,至少要经过编译期和运行期。重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境。由于重排原创 2014-10-28 22:48:06 · 4999 阅读 · 2 评论 -
ExecutorService.invokeAny()和ExecutorService.invokeAll()的源码阅读心得
ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用方式,可以参考我之前的一篇文章。之前的博客按照test and learn的学习方式(有点类似于测试驱动开发),构造了我能想到的几种场景来进行测试,通过分析测试结果,也得出了一些结论,学会了这2个API的使用。本文主要是阅读下J.U.C源码,一则验证下之前的一些推论,二则学习下源码中的一些技巧,这是通过执行测试用例看不到的。这也提示我们:设计API的时候,要站在使用者的角度,考虑他们的调用习惯原创 2014-11-15 19:40:21 · 2515 阅读 · 0 评论 -
ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析
ExecutorService是JDK并发工具包提供的一个核心接口,相当于一个线程池,提供执行任务和管理生命周期的方法。ExecutorService接口中的大部分API都是比较容易上手使用的,本文主要介绍下invokeAll和invokeAll方法的特性和使用。我们先提供几个任务类:一个耗时任务,一个异常任务,一个短时任务。他们会在接下来的测试代码中使用。package tasks;im原创 2014-07-27 16:15:07 · 7729 阅读 · 2 评论 -
J.U.C原子工具类AtomicXXX中,set和lazySet的区别
提到java原子类,不得不说下关键字volatile和内存可见性。内存可见性问题,可以看下《java并发编程实践》讲的很详细。下面的示例代码是错误的,因为没有使用volatile来保证内存的可见性,所以如果1个线程修改了共享变量,那么另外一个线程可能永远也看不到修改后的值。如果将stop修改成volatile类型的,就可以保证一个线程对volatile变量的修改,对另一个线程是可见的。publ原创 2014-11-30 17:14:06 · 6398 阅读 · 0 评论 -
java同步机制:使用synchronize block,还是使用synchronize method
今天在学习java原子类的时候,遇到了这篇博客,看到了同步代码块和同步方法的区别,之前没有意识到,这里记录下。public class CP { private int i = 0; public synchronized int synchronizedMethodGet() { return i; } public int synchronizedBlockGet() {原创 2015-01-20 17:26:55 · 2352 阅读 · 4 评论 -
java并发编程实践学习(二)由可重入锁想到的
创建了一个子类对象的时候,在子类对象内存中,有两份数据,一份继承自父类,一份来自子类,但是他们属于同一个对象(子类对象),只不过是java语法提供了this和super关键字来让我们能够按照需要访问这2份数据而已。这样就产生了子类和父类的概念,但实际上只有子类对象,没有父类对象。父类对象就是子类对象,即父类的synchronized方法和子类的synchronized方法属于同一个对象。原创 2014-03-31 23:10:57 · 3532 阅读 · 6 评论