码迷,mamicode.com
首页 > 编程语言 > 详细

Effective Java 阅读笔记——并发

时间:2016-01-09 18:28:31      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

66:同步访问共享的可变数据

synchronized:1互斥,阻止线程看到的对象处于不一致的状态;2保证线程在进入同步区时能看到变量的被各个线程的所有修改

Java中,除了long或者double,“读”或者“写”一个变量是原子的。注意:是读或者写单个动作是源自的,而不是读写这两个动作整体是原子的。

由于虚拟机会对代码进行优化,所以可能会导致一些错误:可能你想的是在另一线程中改变done的值来终止while循环,但是优化之后却无法做到这样。要避免这样的优化错误,就必须对done同步。

//优化前,即程序员所写
while(!done){
    ++i;
}
//优化后  测试环境为win7的Eclipse不会进行此优化,在HopSpot Server VM中会进行此优化
if(!done){
    wile(true){
       ++i;
    }
}

volatile:可以保证线程之间的通信效果,但是无法保证互斥访问。即任何读线程读到的最近一次由任何线程修改后的值。但应该特别注意一些操作的原子性,比如i++,++操作会先读后写,即即使有volatile,也可能会在++操作读了值之后,+1操作之前而读取到值,即没有读到+1后的值。

67:避免过度同步

避免过度同步:为了避免死锁和数据破坏(一般由锁的可重入机制造成),千万不要在同步区域内部调用外来方法(即可能被覆盖的方法或者由客户端以函数对象提供的方法),应该尽量限制同步区域内部的工作量。外来方法的调用应放在同步区域之外,这叫做“开放调用”,可以避免死锁并极大提高并发性。

当设计一个类的时候,需要考虑是否应该在类的内部实现同步,使之线程安全,并能获得更高的并发性。在这个多核时代,这比不要过度同步更为重要。

过度同步的坏处并不是指获取锁所花费的CPU时间,而是:1失去了并行的机会,以及因为需要确保每个核都有一个一致的内存视图而导致的延迟;2会限制VM优化代码执行的能力

68:executor和task优先于线程

即优先使用Executor和task(即Runnable和Callable)而不是Thread,可以降低创建的线程个数,提高性能,而且可以获得更多的线程策略,极大降低编码难度。但应该认真选择合适的ExecutorService,比如一般的轻量程序选择Executors.newCachedThreadPool,但是对于高负载的服务器,由于缓存线程池可能会根据需求而不断增加新线程,可能导致CPU全部被占用,最终导致奔溃,这时就应该选择Executor.newFixedThreadPool以限制总线程数。

69:并发工具优于wait和notify

70:线程安全性的文档化

71:慎用延迟初始化

72:不要依赖于线程调度器

73:避免使用线程组

 

Effective Java 阅读笔记——并发

标签:

原文地址:http://www.cnblogs.com/andyong/p/5116890.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!