CAS
CAS Compare And Swap 比较并交换
是现代 CPU 广泛支持的一种对内存中共享数据进行操作的一种特殊指令。
CAS的作用:可以将比较和交换转换成原子操作,这个原子操作直接有 CPU 保证
可以保证共享变量赋值时的原子操作, CAS 操作依赖三个值,
-
内存中的值 V
-
旧的预估值 X
-
要修改的新值 B
-
如果旧的预估值 X 等于内存中的值 V ,就将新的值 B 保存到内存中。
CAS 原理
Unsafe 类介绍
class AtomicInteger extends Number implements java.io.Serializable {
private static final long valueOffset
private static final Unsafe Unsafe = Unsafe。getUnsafe();
private volatile int value;
}

乐观锁: CAS 机制
悲观锁: synchornized
JDK 6 synchronized 优化
synchronized 锁升级
JDK 1.6 改进优化,包括偏向锁、轻量级锁和适应性自旋、锁消除、锁粗化等,
这些技术都是为了在线程之间更高效地共享数据、以及解决竞争问题,从而提高程序的执行效率。
无锁 -> 偏向锁 -> 轻量级锁和适应性自旋 -> 重量级锁
Java 对象的布局
学习 Java 对象的布局,在JVM 中, 对象在内存中的布局分三块区域:
- 对象头
- 实例数据
- 对齐数据。
markOop_mark mark word
klass pointer
对象头 = mark word + 类型指针(未开启指针压缩的情况下)
在32位系统中 Mark Word = 4 bytes ,类型指针 = 4bytes, 对象头 = 8 bytes
在64位系统中, Mark Word = 8 bytes , 类型指针 = 8 bytes, 对象头 = 16 bytes
偏向锁
UseBiasedLocking = false 参数关闭偏向锁
大多数情况下,锁不仅不存在多线程竞争,而且总是有同一个线程多次获得, 为了让线程获得锁的代价减小, 偏向锁关键在偏字
偏向锁的原理
当线程第一次访问同步代码快并获取锁时, 偏向锁的处理流程如下:
1、检测 Mark Word 是否为可偏向状态, 是否为偏向锁1 , 锁标识位为01
2、若为可偏向状态,则测试线程 ID 是否为当前线程 ID ,如果是,执行同步代码快,否则执行步骤3
3、如果测试线程 ID 不为当前线程 ID, 则通过 CAS 操作将 Mark Word 的线程 ID 替换为当前线程 ID ,执行同步代码快;
偏向锁在一个线程下执行效率高;
偏向锁的撤销
1、 偏向锁的撤销动作必须等待全局安全点
2、 暂停拥有偏向的线程,判断锁对象是否处在锁定状态
3、 撤销偏向锁,恢复到无锁(标志位01)或轻量级锁(标志位00)的状态
轻量级锁
目的:在多线程交替执行同步代码快的情况下,尽量避免重量级锁引起的性能消耗,但是如果多个线程在同一个时刻进入临界区,会导致轻量级锁膨胀升级重量级锁,所以在轻量级锁的出现并非代替重量级锁
原理:未写完
总结
synchronized 优化方法
尽量使用同步代码快
减少 synchronized 的范围 减少锁的竞争
Looper.getMainLooper(); 通过代码块 而不是修饰方法
/**
* Initialize the current thread as a looper, marking it as an
* application's main looper. See also: {@link #prepare()}
*
* @deprecated The main looper for your application is created by the Android environment,
* so you should never need to call this function yourself.
*/
@Deprecated
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
/**
* Returns the application's main looper, which lives in the main thread of the application.
*/
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
减少 synchronized 的粒度
尽量使用对象而不要使用 class 类型
synchronized (lock) {
queue.remove(priority);
highestPriority = queue.isEmpty() ? Integer.MIN_VALUE : Util.castNonNull(queue.peek());
lock.notifyAll();
}
ConcurrentHashMap 读写分离
HashTable :锁定整个哈希表,一个操作正在进行时, 其他操作也同时锁定,效率低下

ConcurrentHashMap :局部锁定,只锁定桶,对当前元素锁定,其他元素不锁定


总结: 读写分离
读取时不加锁,写入和删除时加锁: 同样的集合例子有:
ConcurrentHashMap , CopyOnWriteArrayList 和 CopyOnWriteSet