以下只是一些概念
1.
Semaphore与
CountDownLatch
Semaphore 可用于控制特定资源请求(线程/操作)数量
CountDownLatch 在功能上类似于Semaphore。区别是,Semaphore允许一次一个线程的话,CountDownLatch可以允许多个线程在特定的时间一起执行。
2.CAS操作
根据英文直译其实可以理解其含义,compare and set.
CAS 操作包含三个操作数 ——
内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。CAS 认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可通常将 CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
3.ABA问题
因为在更改 V 之前,CAS 主要询问“V 的值是否仍为 A”,所以在第一次读取 V 以及对 V 执行 CAS 操作之前,如果将值从 A 改为
B,然后再改回 A,会使基于 CAS 的算法混乱。在这种情况下,CAS 操作会成功,但是在一些情况下,结果可能不是您所预期的。这类问题称为
ABA 问题。
4.原子操作
A与B两个操作。从执行A的线程看,当其他线程执行B时,要么B全部执行完成,要么一点都不执行。这样A与B互为原子操作。要保证数据状态的一致性,要在单一的原子操作中更新所有相关联的状态。
5.可见性
在单线程环境下,读写操作都在一个线程内完成,不存在可见性问题。但是,当读与写操作不在同一个线程内时,就需要有可见性的要求——即可变的共享变量对所有线程都是可见的。
6.重排序
JVM实现中,线程内部维持顺序化语义。如果程序的最终结果等同于它在严格的顺序化环境下的结果,那么指令的执行顺序就可能与代码的顺序不一致。这个过程通过叫做指令的重排序。比如Java存储模型允许编译器重排序操作指令,在寄存器中缓存数值,还允许CPU重排序,并在处理器的缓存中缓存数值。
当然,在没有同步的多线程情况下,编译器,处理器,运行时安排操作的执行顺序可能完全出人意料。
7.内部锁
每个Java对象都可以隐士的扮演一个用于同步的锁的角色。比如synchronized(object){},执行线程进入synchronized块
之前自动获得锁。无论是正确执行或是抛出异常,最终都会释放该锁。内部锁是一种互斥锁(mutex)——至多只有一个线程可以拥有锁。JDK中有该锁的实
现。
8.锁与内存
锁不仅仅是关于同步与互斥,也是关于内存可见性的。为了保证所有线程都能访问共享变量的最新值,读和写的线程必须使用公用的锁进行同步。
9.锁与volatile
加锁可以保证可见性与原子性,volatile只能保证可见性。
10.happen-before法则
Java存储模型有一个happens-before原则,就是如果动作B要看到动作A的执行结果(无论A/B是否在同一个线程里面执行),那么A/B就需要满足happens-before关系。比如一个对象构造函数的结束happens-before与该对象的finalizer的开始
参考:https://www.ibm.com/developerworks/cn/java/j-jtp11234/
http://www.ibm.com/developerworks/cn/java/j-5things5.html
http://www.blogjava.net/xylz/archive/2010/07/03/325168.html
《Java 并发编程实践》