随笔分类 -  Java并发编程实战

摘要:在没有充分同步的程序中,如果调度器采用不恰当的方式来交替执行不同线程的操作,那么将导致不正确的结果。更糟的是,JMM还使得不同线程看到的操作执行顺序是不同的,从而导致在缺乏同步的发问下,要推断操作的执行顺序将变得更加复杂。各种使操作延迟或者看似乱序执行的不同原因,都可以归为重排序。JMM为程序中所有... 阅读全文

posted @ 2015-10-27 09:06 a0000 阅读(194) 评论(0) 推荐(0)

摘要:与基于锁的方案相比,非阻塞算法在设计和实现上都要复杂得多,但它们在可伸缩性和活跃性上却拥有巨大的优势。由于非阻塞算法可以使多个线程在竞争相同的数据时不会发生阻塞,因此它能在粒度更细的层次上进行协调,并且极大地减少调度开销。而且,在非阻塞算法中不存在死锁和其他活跃性问题。在基于锁的算法中,如果一个线程... 阅读全文

posted @ 2015-10-27 08:49 a0000 阅读(198) 评论(0) 推荐(0)

摘要:当使用条件等待时(例如Object.wait或Condition.await):通常都有一个条件谓词——包括一些对象状态的测试,线程在执行前必须首先通过这些测试。在调用wait之前测试条件谓词,并且从wait中返回时再次进行测试。在一个循环中调用wait。确保使用与条件队列相关的锁来保护构造条件谓词... 阅读全文

posted @ 2015-10-27 08:30 a0000 阅读(218) 评论(0) 推荐(0)

摘要:性能是一个不断变化的指标,如果在昨天的测试基准中发现X比Y更快,那么在今天就可能已经过时了。在激烈竞争的情况下,在非公平锁的性能高于公平锁的性能的一个原因是:在恢复一个被挂起的线程与该线程真正开始运行之间存在着严重的延迟。假设线程A持有一个锁,并且线程B请求这个锁。由于这个锁已被线程A持有,因此B将... 阅读全文

posted @ 2015-10-23 20:45 a0000 阅读(156) 评论(0) 推荐(0)

摘要:测试结果表明,LinkedBlockingQueue的可伸缩性要高于ArrayBlockingQueue。初看起来,这个结果有些奇怪:链表队列在每次插入元素时,都必须分配一个链表节点对象,这似乎比基于数组的队列执行了更多的工作。然而,虽然它拥有更好的内存分配与GC等开销,但与基于数组的队列相比,链表... 阅读全文

posted @ 2015-10-23 09:23 a0000 阅读(281) 评论(0) 推荐(0)

摘要:要想通过并发来获得更好的性能,需要努力做好两件事情:更有效的利用现有处理资源以及在出现新的处理资源时使程序尽可能地利用这些新资源。第6章介绍了如何识别任务的逻辑边界并将应用程序分解为多个子任务。然而要预测应用程序在某个多处理器系统中将实现多大的加速比,还需要找出任务中的串行部分。单个任务的处理时间不... 阅读全文

posted @ 2015-10-23 09:02 a0000 阅读(154) 评论(0) 推荐(0)

摘要:如果每个需要锁L和锁M的线程都以相同的顺序来获取L和M,那么就不会发生死锁了。解决这个问题,必须定义锁的顺序,并在整个应用程序中都按照这个顺序来获取锁。在制定锁的顺序时,可以使用System.identityHashCode方法,该方法将返回由Object.hashCode返回的值。 priv... 阅读全文

posted @ 2015-10-23 08:23 a0000 阅读(202) 评论(0) 推荐(0)

摘要:ThreadLocal使每个线程都可以拥有某个变量的一个私有“版本”。然而,只要条件允许,Executor可以自由地重用这些线程。在标准的Executor实现中,当执行需求较低时将回收空闲线程,而当需求增加时将添加新的线程,并且如果从任务中抛出了一个未检查异常,那么将用一个新的工作者线程来替代抛出异... 阅读全文

posted @ 2015-09-24 09:11 a0000 阅读(165) 评论(0) 推荐(0)

摘要:一个在行为良好的软件与勉强运行的软件之间的最主要区别就是,行为良好的软件能很完善地处理失败、关闭和取消等过程。取消某个操作的原因很多:用户取消。有时间限制的操作。例如,某个应用程序需要在有限时间内搜索问题空间,并在这个时间内选择最佳的解决方案。应用程序事件。例如,应用程序对某个问题空间进行分解并搜索... 阅读全文

posted @ 2015-09-24 00:04 a0000 阅读(216) 评论(0) 推荐(0)

摘要:如果可运行的线程数量多于可用处理器的数量,那么有引动线程将闲置。大量空闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量线程在竞争CPU资源时还将产生其他的性能开销。任务是一组逻辑工作单元,而线程则是使任务异步执行的机制。我们已经分析了两种通过线程来执行任务的策略,即把所有任务放在单个线程中串行... 阅读全文

posted @ 2015-09-23 23:43 a0000 阅读(212) 评论(0) 推荐(0)

摘要:同步容包括Vector和Hashtable,这些同步的封装器类是由Collections.synchronizedXxx等工厂方法创建的。这些类实现线程安全的试是: 将它们的状态封装起来,并对每个公有方法都进行同步,使得每次只有一个线程能访问容器的状态。同步容器类都是线程安全的,但在某些情况下可能需... 阅读全文

posted @ 2015-09-22 09:15 a0000 阅读(229) 评论(0) 推荐(0)

摘要:同步还有别一个重要的方面:内存可见性。(个人理解,对对象的修改在其他线程能立即看到)失效数据:读到的数据已经失效(读到的是某线程修改该对象之前的数据)在多线程程序中使用共享且可变的long和double等类型的变量也是不安全的,除非用关键字volatile来声明它们,或者用锁保护起来。加锁机制既可以... 阅读全文

posted @ 2015-08-26 07:39 a0000 阅读(168) 评论(0) 推荐(0)

摘要:要保持状态的一致性, 就需要在单个原子操作中更新所有相关的状态变量。同步代码块包括两部分:一个作为锁的对象引用, 一个作为由这个锁保护的代码块。以synchronized来修饰的方法就是一种横跨整个方法体的同步代码块, 其中该同步代码块的锁就是方法调用所在的对象。静态的synchronized方法以... 阅读全文

posted @ 2015-08-03 09:50 a0000 阅读(146) 评论(0) 推荐(0)

导航