java并发编程实战(java concurrency in practice)

第一章
 
线程共享进程范围内的资源,但每一个线程都有各自的程序计数器、栈以及局部变量等。
多个线程能够同时调度到多个CPU上运行。
 
线程的优点?
在服务应用程序中,能够提高资源利用率以及系统吞吐率,发挥多处理器的强大功能。
 
线程的优先级  执行时间  线程切换须要额外的开销
 
第二章
 
若是多个线程访问同一个可变的状态变量是没有使用合适的同步,那么程序就会出现错误,有如下三种方法修复这种问题。
一、不在线程之间共享该状态变量
二、将状态变量改成不可变的变量
三、在访问状态变量时使用同步
 
什么是线程安全?本身百度
 
无状态对象必定是线程安全的
 
注意count++这类操做的问题:不是原子的,其实是三部操做 读取-修改-写入
 
什么是竞态条件?
在并发编程中,因为不恰当的执行时序从而使得结果变得不可靠。常见的竞态条件类型就是“先检查后执行” ,例如常见的对象懒加载
 
一个包:java.concurrent.atomic
 
 
内置锁:加锁机制,java中用于确保原子性的内置机制。同步代码块、同步方法
以synchronized来修饰的方法叫同步方法,该同步代码块的锁就是方法调用所在的对象,静态的 synchronized方法以Class对象做为锁
 
每一个java对象均可以用做实现一个同步的锁,称为内置锁或监视器锁。
线程在进入同步代码块前会自动得到锁,而且在退出同步代码块时自动释放锁。
 
内置锁是可重入的。
 
理解一句话:状态变量是由这个锁保护的。
 
锁不要滥用,同步代码块太大会引发不良并发,大大拉低程序性能。当执行较长的计算或者可能没法快速完成的操做时(如网络I/O、控制台I/O),必定不要持有锁。
 
第三章
 
同步机制不仅是为了实现原子性或者肯定“临界区”,还确保了多个线程之间对内存操做的可见性。
加锁的含义不只仅局限于互斥行为,还包含内存可见性。
 
注意重排序现象
 
最低安全性:当线程在没有进行同步的状况下读取变量时,可能会的到一个时效值,但至少这个值是由以前某个线程设置的,而不是一个随机值。
非volatile类型的64位数值变量(double和long)不适用于最低安全性,由于JVM容许将64位的读操做或写操做分解为两个32位的操做
 
一种稍弱的同步机制,即volatile变量。
加锁机制便可以确保可见性又能够确保原子性,而volatile变量只能确保可见性。(确保只有单个线程更新变量的值时能够用 volatile变量 )
 
发布一个对象
意思是指,是对象可以在当前做用域以外的代码中使用。
 
逸出
当某个不该该发布的对象被发布时,被称为逸出。
 
发布对象的方式:
发布对象最简单的方法是将对象的引用保存到一个公有的静态变量中。
从非私有的方法中返回一个对象的引用,如java web开发中经常使用的get set方法。
发布一个内部类的实例(内部类实例包含外部类实例的引用)
 
不要在构造过程当中使用this引用逸出(只有在构造函数返回时,this引用才应该从线程中逸出)
 
线程封闭
若是在单线程内访问数据,就不须要同步。这种技术称为线程封闭。
 
实现线程封闭的方法:
Ad-hoc线程封闭(了解)
栈封闭(在方法内的局部变量访问对象,熟悉)
ThreadLocal类(经常使用)
 
ThreadLocal类
这个类能使线程中的某个值与保存值的对象关联起来。该类提供get与set等访问接口或方法,这些方法为每一个使用该变量的线程都存有一份独立副本,所以get老是返回当前线程在调用set时设置的最新值。当线程终止后,这些值会做为垃圾回收。
 
不可变对象必定是线程安全的
 
知足如下条件时,对象才是不可变的:
对象建立之后其状态就不能够修改
对象的全部域都是final类型
对象是正确建立的(建立对象时,this引用没有逸出)
相关文章
相关标签/搜索