并发相关概念
锁
互斥锁:互相排斥,上锁或释放锁会导致内核态上下文切换,没有获得锁的情况下线程进入休眠。
自旋锁:用户态不停尝试获取锁,直到锁获取成功或者线程切换。
在多核 / 多CPU 的系统上,特别是大量的线程只会短时间的持有锁的时候,这时如果使用 互斥锁,在使线程睡眠和唤醒上浪费大量的时间,也许会显著降低程序的运行性能。使用 自旋锁,线程可以充分利用系统调度程序分配的时间片(经常阻塞很短的时间,不用休眠,然后马上继续它们后面的工作了),以达到更高的处理能力和吞吐量。
悲观锁(Pssimistic Lock):每次操作数据时都会上锁,其他想操作数据则会被block。
乐观锁(Optimistic Lock):每次操作数据时不会上锁,但在更新数据时,会判断一下期间其他地方有没有更新该数据。
乐观锁用于写数据较少情况下。
注:根据获得锁的先后顺序,是否会按照该顺序进入lock又分成公平锁和非公平锁。
另外还有一种叫可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。在JAVA环境下 ReentrantLock 和synchronized 都是可重入锁
优先级反转(Priority Inversion):当一个持有所的线程被延迟执行的话,其他所有需要这个锁的现成将被block住,当被block的线程优先级高而当前持有锁的优先级低,则会导致优先级反转。
CAS(Compare and Swarp):无锁算法中经常用到,使用CAS时不需要像上锁那样需要一次上下文切换,通常使用如下:
1 do{ 2 备份旧的数据; 3 基于旧数据构造新的数据; 4 }while(!CAS(内存地址,备份的旧数据,新数据))
Memory Barrier:由于现代CPU是乱序执行命令的,
Cache:多核情况下可能有多个Cache对应不同的核,对其中一个Cache数据的操作则可能会影响到其他Cache,这就是缓存一致性问题。详见http://kb.cnblogs.com/page/504824/
Cache Line:一、二级缓存更新时的最小单元,通常32到256字节,对该单元的操作会影响到映射到内存的数据的读写。
Java中使用到的并发队列为
- ConcurrentLinkedQueue
JDK7提供了7个阻塞队列。分别是
- ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
- LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
- PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
- DelayQueue:一个使用优先级队列实现的无界阻塞队列。
- SynchronousQueue:一个不存储元素的阻塞队列。
- LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
- LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。
参考
http://www.cnblogs.com/Mainz/p/3546347.html